]> git.saurik.com Git - apple/javascriptcore.git/commitdiff
JavaScriptCore-621.1.tar.gz ios-42 v621.1
authorApple <opensource@apple.com>
Sat, 7 May 2011 12:40:31 +0000 (12:40 +0000)
committerApple <opensource@apple.com>
Sat, 7 May 2011 12:40:31 +0000 (12:40 +0000)
351 files changed:
API/APICast.h
API/APIShims.h
API/JSBase.cpp
API/JSCallbackFunction.cpp
API/JSCallbackObject.cpp
API/JSCallbackObject.h
API/JSCallbackObjectFunctions.h
API/JSClassRef.cpp
API/JSContextRef.cpp
API/JSObjectRef.cpp
API/JSObjectRefPrivate.h [new file with mode: 0644]
API/JSStringRef.h
API/JSValueRef.cpp
API/JSValueRef.h
API/JSWeakObjectMapRefInternal.h [new file with mode: 0644]
API/JSWeakObjectMapRefPrivate.cpp [new file with mode: 0644]
API/JSWeakObjectMapRefPrivate.h [new file with mode: 0644]
API/WebKitAvailability.h
API/tests/testapi.c
Android.mk
Android.v8.wtf.mk
DerivedSources.make
DerivedSources.pro
GNUmakefile.am
JavaScriptCore.exp
JavaScriptCore.gyp/JavaScriptCore.gyp
JavaScriptCore.gypi
JavaScriptCore.iPhone.order [deleted file]
JavaScriptCore.order
JavaScriptCore.pri
JavaScriptCore.pro
assembler/ARMAssembler.cpp
assembler/ARMAssembler.h
assembler/ARMv7Assembler.h
assembler/AbstractMacroAssembler.h
assembler/AssemblerBuffer.h
assembler/AssemblerBufferWithConstantPool.h
assembler/CodeLocation.h
assembler/LinkBuffer.h
assembler/MIPSAssembler.h [new file with mode: 0644]
assembler/MacroAssembler.h
assembler/MacroAssemblerARM.h
assembler/MacroAssemblerARMv7.h
assembler/MacroAssemblerCodeRef.h
assembler/MacroAssemblerMIPS.h [new file with mode: 0644]
assembler/MacroAssemblerX86.h
assembler/MacroAssemblerX86Common.h
assembler/MacroAssemblerX86_64.h
assembler/RepatchBuffer.h
assembler/X86Assembler.h
bytecode/CodeBlock.cpp
bytecode/CodeBlock.h
bytecode/EvalCodeCache.h
bytecode/Instruction.h
bytecode/JumpTable.cpp
bytecode/Opcode.h
bytecode/SamplingTool.cpp
bytecompiler/BytecodeGenerator.cpp
bytecompiler/BytecodeGenerator.h
bytecompiler/NodesCodegen.cpp
config.h
create_hash_table
create_jit_stubs [new file with mode: 0644]
create_regex_tables [new file with mode: 0644]
create_rvct_stubs [deleted file]
debugger/Debugger.cpp
debugger/DebuggerCallFrame.cpp
interpreter/CallFrame.h
interpreter/Interpreter.cpp
interpreter/Interpreter.h
interpreter/RegisterFile.cpp
interpreter/RegisterFile.h
jit/ExecutableAllocator.cpp
jit/ExecutableAllocator.h
jit/ExecutableAllocatorFixedVMPool.cpp
jit/ExecutableAllocatorPosix.cpp
jit/ExecutableAllocatorSymbian.cpp
jit/ExecutableAllocatorWin.cpp
jit/JIT.cpp
jit/JIT.h
jit/JITArithmetic.cpp
jit/JITArithmetic32_64.cpp [new file with mode: 0644]
jit/JITCall.cpp
jit/JITCode.h
jit/JITInlineMethods.h
jit/JITOpcodes.cpp
jit/JITOpcodes32_64.cpp [new file with mode: 0644]
jit/JITPropertyAccess.cpp
jit/JITPropertyAccess32_64.cpp [new file with mode: 0644]
jit/JITStubCall.h
jit/JITStubs.cpp
jit/JITStubs.h
jit/JSInterfaceJIT.h [new file with mode: 0644]
jit/SpecializedThunkJIT.h [new file with mode: 0644]
jit/ThunkGenerators.cpp [new file with mode: 0644]
jit/ThunkGenerators.h [new file with mode: 0644]
jsc.cpp
jsc.pro
make-generated-sources.sh
os-win32/stdint.h
parser/Grammar.y
parser/Lexer.cpp
parser/Nodes.h
parser/Parser.cpp
pcre/pcre_exec.cpp
profiler/CallIdentifier.h
profiler/Profile.cpp
profiler/ProfileGenerator.cpp
profiler/ProfileNode.cpp
qt/api/QtScript.pro
qt/api/qscriptconverter_p.h
qt/api/qscriptengine.cpp
qt/api/qscriptengine.h
qt/api/qscriptengine_p.cpp
qt/api/qscriptengine_p.h
qt/api/qscriptprogram.cpp [new file with mode: 0644]
qt/api/qscriptprogram.h [new file with mode: 0644]
qt/api/qscriptprogram_p.h [new file with mode: 0644]
qt/api/qscriptstring.cpp [new file with mode: 0644]
qt/api/qscriptstring.h [new file with mode: 0644]
qt/api/qscriptstring_p.h [new file with mode: 0644]
qt/api/qscriptsyntaxcheckresult.cpp [new file with mode: 0644]
qt/api/qscriptsyntaxcheckresult.h [new file with mode: 0644]
qt/api/qscriptsyntaxcheckresult_p.h [new file with mode: 0644]
qt/api/qscriptvalue.cpp
qt/api/qscriptvalue_p.h
qt/api/qtscriptglobal.h
qt/tests/qscriptengine/qscriptengine.pro
qt/tests/qscriptengine/tst_qscriptengine.cpp
qt/tests/qscriptstring/qscriptstring.pro [new file with mode: 0644]
qt/tests/qscriptstring/tst_qscriptstring.cpp [new file with mode: 0644]
qt/tests/qscriptvalue/qscriptvalue.pro
qt/tests/qscriptvalue/tst_qscriptvalue.cpp
qt/tests/qscriptvalue/tst_qscriptvalue.h [new file with mode: 0644]
qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp [new file with mode: 0644]
qt/tests/tests.pri
qt/tests/tests.pro
runtime/ArrayPrototype.cpp
runtime/CachedTranscendentalFunction.h [new file with mode: 0644]
runtime/Collector.cpp
runtime/Collector.h
runtime/CollectorHeapIterator.h
runtime/Completion.cpp
runtime/Completion.h
runtime/DateConstructor.cpp
runtime/DateConversion.cpp
runtime/DatePrototype.cpp
runtime/Error.cpp
runtime/ErrorPrototype.cpp
runtime/ExceptionHelpers.cpp
runtime/ExceptionHelpers.h
runtime/Executable.cpp
runtime/Executable.h
runtime/FunctionConstructor.cpp
runtime/FunctionPrototype.cpp
runtime/GetterSetter.h
runtime/Identifier.cpp
runtime/Identifier.h
runtime/InitializeThreading.cpp
runtime/InternalFunction.cpp
runtime/JSAPIValueWrapper.h
runtime/JSActivation.cpp
runtime/JSActivation.h
runtime/JSArray.cpp
runtime/JSArray.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/JSImmediate.h
runtime/JSLock.cpp
runtime/JSNumberCell.cpp
runtime/JSNumberCell.h
runtime/JSONObject.cpp
runtime/JSONObject.h
runtime/JSObject.cpp
runtime/JSObject.h
runtime/JSPropertyNameIterator.h
runtime/JSStaticScopeObject.cpp
runtime/JSStaticScopeObject.h
runtime/JSString.cpp
runtime/JSString.h
runtime/JSStringBuilder.h [new file with mode: 0644]
runtime/JSTypeInfo.h
runtime/JSValue.cpp
runtime/JSValue.h
runtime/JSVariableObject.h
runtime/JSZombie.h
runtime/LiteralParser.cpp
runtime/Lookup.cpp
runtime/Lookup.h
runtime/MathObject.cpp
runtime/NativeErrorConstructor.cpp
runtime/NativeErrorConstructor.h
runtime/NativeErrorPrototype.cpp
runtime/NativeErrorPrototype.h
runtime/NumberConstructor.cpp
runtime/NumberPrototype.cpp
runtime/NumericStrings.h
runtime/ObjectPrototype.cpp
runtime/Operations.cpp
runtime/Operations.h
runtime/PropertyNameArray.cpp
runtime/PropertySlot.cpp
runtime/PropertySlot.h
runtime/RegExp.cpp
runtime/RegExp.h
runtime/RegExpCache.cpp [new file with mode: 0644]
runtime/RegExpCache.h [new file with mode: 0644]
runtime/RegExpConstructor.cpp
runtime/RegExpKey.h [new file with mode: 0644]
runtime/RegExpMatchesArray.h
runtime/RegExpObject.cpp
runtime/RegExpPrototype.cpp
runtime/RopeImpl.cpp [new file with mode: 0644]
runtime/RopeImpl.h [new file with mode: 0644]
runtime/SmallStrings.cpp
runtime/SmallStrings.h
runtime/StringBuilder.h
runtime/StringConstructor.cpp
runtime/StringPrototype.cpp
runtime/Structure.cpp
runtime/Structure.h
runtime/StructureTransitionTable.h
runtime/Terminator.h [new file with mode: 0644]
runtime/TimeoutChecker.cpp
runtime/UString.cpp
runtime/UString.h
runtime/UStringImpl.cpp [deleted file]
runtime/UStringImpl.h
runtime/WeakGCPtr.h
tests/perf/bench-allocate-nonretained.js [new file with mode: 0644]
tests/perf/bench-allocate-retained.js [new file with mode: 0644]
wrec/CharacterClass.cpp [deleted file]
wrec/CharacterClass.h [deleted file]
wrec/CharacterClassConstructor.cpp [deleted file]
wrec/CharacterClassConstructor.h [deleted file]
wrec/Escapes.h [deleted file]
wrec/Quantifier.h [deleted file]
wrec/WREC.cpp [deleted file]
wrec/WREC.h [deleted file]
wrec/WRECFunctors.cpp [deleted file]
wrec/WRECFunctors.h [deleted file]
wrec/WRECGenerator.cpp [deleted file]
wrec/WRECGenerator.h [deleted file]
wrec/WRECParser.cpp [deleted file]
wrec/WRECParser.h [deleted file]
wscript
wtf/ASCIICType.h
wtf/AlwaysInline.h
wtf/Assertions.h
wtf/Atomics.h [new file with mode: 0644]
wtf/Complex.h [new file with mode: 0644]
wtf/CurrentTime.cpp
wtf/CurrentTime.h
wtf/FastMalloc.cpp
wtf/FastMalloc.h
wtf/HashCountedSet.h
wtf/HashMap.h
wtf/ListHashSet.h
wtf/MD5.cpp [new file with mode: 0644]
wtf/MD5.h [new file with mode: 0644]
wtf/MainThread.cpp
wtf/MainThread.h
wtf/MathExtras.h
wtf/OwnFastMallocPtr.h
wtf/OwnPtr.h
wtf/OwnPtrCommon.h
wtf/OwnPtrWin.cpp [deleted file]
wtf/PassRefPtr.h
wtf/Platform.h
wtf/PtrAndFlags.h [deleted file]
wtf/RandomNumber.h
wtf/RefPtr.h
wtf/StaticConstructors.h [new file with mode: 0644]
wtf/StdLibExtras.h
wtf/StringExtras.h
wtf/ThreadSafeShared.h [new file with mode: 0644]
wtf/ThreadSpecific.h
wtf/Threading.h
wtf/ThreadingPrimitives.h [new file with mode: 0644]
wtf/ThreadingPthreads.cpp
wtf/ThreadingWin.cpp
wtf/VMTags.h
wtf/ValueCheck.h
wtf/Vector.h
wtf/Vector3.h [new file with mode: 0644]
wtf/VectorTraits.h
wtf/WTFThreadData.cpp [new file with mode: 0644]
wtf/WTFThreadData.h [new file with mode: 0644]
wtf/brew/MainThreadBrew.cpp [new file with mode: 0644]
wtf/brew/OwnPtrBrew.cpp [new file with mode: 0644]
wtf/brew/ShellBrew.h [new file with mode: 0644]
wtf/brew/SystemMallocBrew.h [new file with mode: 0644]
wtf/chromium/ChromiumThreading.h
wtf/chromium/MainThreadChromium.cpp
wtf/dtoa.cpp
wtf/efl/MainThreadEfl.cpp [new file with mode: 0644]
wtf/gobject/GOwnPtr.cpp [new file with mode: 0644]
wtf/gobject/GOwnPtr.h [new file with mode: 0644]
wtf/gobject/GRefPtr.cpp [new file with mode: 0644]
wtf/gobject/GRefPtr.h [new file with mode: 0644]
wtf/gtk/GOwnPtr.cpp [deleted file]
wtf/gtk/GOwnPtr.h [deleted file]
wtf/gtk/GRefPtr.cpp [deleted file]
wtf/gtk/GRefPtr.h [deleted file]
wtf/gtk/ThreadingGtk.cpp
wtf/mac/MainThreadMac.mm
wtf/qt/MainThreadQt.cpp
wtf/qt/StringQt.cpp [new file with mode: 0644]
wtf/qt/ThreadingQt.cpp
wtf/symbian/BlockAllocatorSymbian.cpp [new file with mode: 0644]
wtf/symbian/BlockAllocatorSymbian.h [new file with mode: 0644]
wtf/text/AtomicString.cpp [new file with mode: 0644]
wtf/text/AtomicString.h [new file with mode: 0644]
wtf/text/AtomicStringImpl.h [new file with mode: 0644]
wtf/text/CString.cpp [new file with mode: 0644]
wtf/text/CString.h [new file with mode: 0644]
wtf/text/StringBuffer.h [new file with mode: 0644]
wtf/text/StringHash.h [new file with mode: 0644]
wtf/text/StringImpl.cpp [new file with mode: 0644]
wtf/text/StringImpl.h [new file with mode: 0644]
wtf/text/StringImplBase.h [new file with mode: 0644]
wtf/text/StringStatics.cpp [new file with mode: 0644]
wtf/text/WTFString.cpp [new file with mode: 0644]
wtf/text/WTFString.h [new file with mode: 0644]
wtf/unicode/Collator.h
wtf/unicode/CollatorDefault.cpp
wtf/unicode/glib/UnicodeGLib.h
wtf/unicode/icu/CollatorICU.cpp
wtf/unicode/qt4/UnicodeQt4.h
wtf/url/src/URLComponent.h [new file with mode: 0644]
wtf/url/src/URLSegments.cpp [new file with mode: 0644]
wtf/url/src/URLSegments.h [new file with mode: 0644]
wtf/url/wtfurl.gyp [new file with mode: 0644]
wtf/win/MainThreadWin.cpp
wtf/win/OwnPtrWin.cpp [new file with mode: 0644]
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 4284c448a05593c2ee569660a3c839ea05ea969f..ba00d02e1071888e34422544356ae3d6644a5eff 100644 (file)
@@ -29,7 +29,6 @@
 #include "JSAPIValueWrapper.h"
 #include "JSGlobalObject.h"
 #include "JSValue.h"
 #include "JSAPIValueWrapper.h"
 #include "JSGlobalObject.h"
 #include "JSValue.h"
-#include <wtf/Platform.h>
 #include <wtf/UnusedParam.h>
 
 namespace JSC {
 #include <wtf/UnusedParam.h>
 
 namespace JSC {
index d7276ec32337c68515ec0d25c279f9b9db0b1b7a..892068d916746d6788de63cbecd4a205f37f2db0 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "CallFrame.h"
 #include "JSLock.h"
 
 #include "CallFrame.h"
 #include "JSLock.h"
+#include <wtf/WTFThreadData.h>
 
 namespace JSC {
 
 
 namespace JSC {
 
@@ -35,7 +36,7 @@ class APIEntryShimWithoutLock {
 protected:
     APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread)
         : m_globalData(globalData)
 protected:
     APIEntryShimWithoutLock(JSGlobalData* globalData, bool registerThread)
         : m_globalData(globalData)
-        , m_entryIdentifierTable(setCurrentIdentifierTable(globalData->identifierTable))
+        , m_entryIdentifierTable(wtfThreadData().setCurrentIdentifierTable(globalData->identifierTable))
     {
         if (registerThread)
             globalData->heap.registerThread();
     {
         if (registerThread)
             globalData->heap.registerThread();
@@ -45,7 +46,7 @@ protected:
     ~APIEntryShimWithoutLock()
     {
         m_globalData->timeoutChecker.stop();
     ~APIEntryShimWithoutLock()
     {
         m_globalData->timeoutChecker.stop();
-        setCurrentIdentifierTable(m_entryIdentifierTable);
+        wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable);
     }
 
 private:
     }
 
 private:
@@ -65,7 +66,7 @@ public:
     // JSPropertyNameAccumulator only has a globalData.
     APIEntryShim(JSGlobalData* globalData, bool registerThread = true)
         : APIEntryShimWithoutLock(globalData, registerThread)
     // JSPropertyNameAccumulator only has a globalData.
     APIEntryShim(JSGlobalData* globalData, bool registerThread = true)
         : APIEntryShimWithoutLock(globalData, registerThread)
-        , m_lock(globalData->isSharedInstance ? LockForReal : SilenceAssertionsOnly)
+        , m_lock(globalData->isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
     {
     }
 
     {
     }
 
@@ -79,14 +80,12 @@ public:
         : m_dropAllLocks(exec)
         , m_globalData(&exec->globalData())
     {
         : m_dropAllLocks(exec)
         , m_globalData(&exec->globalData())
     {
-        resetCurrentIdentifierTable();
-        m_globalData->timeoutChecker.start();
+        wtfThreadData().resetCurrentIdentifierTable();
     }
 
     ~APICallbackShim()
     {
     }
 
     ~APICallbackShim()
     {
-        m_globalData->timeoutChecker.stop();
-        setCurrentIdentifierTable(m_globalData->identifierTable);
+        wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable);
     }
 
 private:
     }
 
 private:
index ebfeafa820a7e703fa59b27d8e7631f126e5ae49..c5f1b15ea90c1088852425e65ca7b35c86da086a 100644 (file)
@@ -38,6 +38,7 @@
 #include <runtime/JSGlobalObject.h>
 #include <runtime/JSLock.h>
 #include <runtime/JSObject.h>
 #include <runtime/JSGlobalObject.h>
 #include <runtime/JSLock.h>
 #include <runtime/JSObject.h>
+#include <wtf/text/StringHash.h>
 
 using namespace JSC;
 
 
 using namespace JSC;
 
index 0e434d960eac8f692f85a05fe74bcff55a335896..63c8add854cd59e52213b8706b2bab6773f476fc 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "config.h"
  */
 
 #include "config.h"
-#include <wtf/Platform.h>
 #include "JSCallbackFunction.h"
 
 #include "APIShims.h"
 #include "JSCallbackFunction.h"
 
 #include "APIShims.h"
index 2fde0f8ee4ab2e1071364cf1f4c138299e1a5bcf..b36c19414473121bce973eab757dd36a1da995b0 100644 (file)
@@ -28,6 +28,7 @@
 #include "JSCallbackObject.h"
 
 #include "Collector.h"
 #include "JSCallbackObject.h"
 
 #include "Collector.h"
+#include <wtf/text/StringHash.h>
 
 namespace JSC {
 
 
 namespace JSC {
 
index adb5b602a75e86fe99d055298c174fbefaf32414..1cf7a02b256e11521d8a699ec04f462d47bd81cb 100644 (file)
 
 namespace JSC {
 
 
 namespace JSC {
 
+struct JSCallbackObjectData {
+    JSCallbackObjectData(void* privateData, JSClassRef jsClass)
+        : privateData(privateData)
+        , jsClass(jsClass)
+    {
+        JSClassRetain(jsClass);
+    }
+    
+    ~JSCallbackObjectData()
+    {
+        JSClassRelease(jsClass);
+    }
+    
+    JSValue getPrivateProperty(const Identifier& propertyName) const
+    {
+        if (!m_privateProperties)
+            return JSValue();
+        return m_privateProperties->getPrivateProperty(propertyName);
+    }
+    
+    void setPrivateProperty(const Identifier& propertyName, JSValue value)
+    {
+        if (!m_privateProperties)
+            m_privateProperties.set(new JSPrivatePropertyMap);
+        m_privateProperties->setPrivateProperty(propertyName, value);
+    }
+    
+    void deletePrivateProperty(const Identifier& propertyName)
+    {
+        if (!m_privateProperties)
+            return;
+        m_privateProperties->deletePrivateProperty(propertyName);
+    }
+
+    void markChildren(MarkStack& markStack)
+    {
+        if (!m_privateProperties)
+            return;
+        m_privateProperties->markChildren(markStack);
+    }
+
+    void* privateData;
+    JSClassRef jsClass;
+    struct JSPrivatePropertyMap {
+        JSValue getPrivateProperty(const Identifier& propertyName) const
+        {
+            PrivatePropertyMap::const_iterator location = m_propertyMap.find(propertyName.ustring().rep());
+            if (location == m_propertyMap.end())
+                return JSValue();
+            return location->second;
+        }
+        
+        void setPrivateProperty(const Identifier& propertyName, JSValue value)
+        {
+            m_propertyMap.set(propertyName.ustring().rep(), value);
+        }
+        
+        void deletePrivateProperty(const Identifier& propertyName)
+        {
+            m_propertyMap.remove(propertyName.ustring().rep());
+        }
+
+        void markChildren(MarkStack& markStack)
+        {
+            for (PrivatePropertyMap::iterator ptr = m_propertyMap.begin(); ptr != m_propertyMap.end(); ++ptr) {
+                if (ptr->second)
+                    markStack.append(ptr->second);
+            }
+        }
+
+    private:
+        typedef HashMap<RefPtr<UString::Rep>, JSValue, IdentifierRepHash> PrivatePropertyMap;
+        PrivatePropertyMap m_propertyMap;
+    };
+    OwnPtr<JSPrivatePropertyMap> m_privateProperties;
+};
+
+    
 template <class Base>
 class JSCallbackObject : public Base {
 public:
 template <class Base>
 class JSCallbackObject : public Base {
 public:
@@ -52,6 +130,21 @@ public:
     { 
         return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), Base::AnonymousSlotCount); 
     }
     { 
         return Structure::create(proto, TypeInfo(ObjectType, StructureFlags), Base::AnonymousSlotCount); 
     }
+    
+    JSValue getPrivateProperty(const Identifier& propertyName) const
+    {
+        return m_callbackObjectData->getPrivateProperty(propertyName);
+    }
+    
+    void setPrivateProperty(const Identifier& propertyName, JSValue value)
+    {
+        m_callbackObjectData->setPrivateProperty(propertyName, value);
+    }
+    
+    void deletePrivateProperty(const Identifier& propertyName)
+    {
+        m_callbackObjectData->deletePrivateProperty(propertyName);
+    }
 
 protected:
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | Base::StructureFlags;
 
 protected:
     static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesHasInstance | OverridesMarkChildren | OverridesGetPropertyNames | Base::StructureFlags;
@@ -79,6 +172,12 @@ private:
     virtual CallType getCallData(CallData&);
     virtual const ClassInfo* classInfo() const { return &info; }
 
     virtual CallType getCallData(CallData&);
     virtual const ClassInfo* classInfo() const { return &info; }
 
+    virtual void markChildren(MarkStack& markStack)
+    {
+        Base::markChildren(markStack);
+        m_callbackObjectData->markChildren(markStack);
+    }
+
     void init(ExecState*);
  
     static JSCallbackObject* asCallbackObject(JSValue);
     void init(ExecState*);
  
     static JSCallbackObject* asCallbackObject(JSValue);
@@ -86,27 +185,10 @@ private:
     static JSValue JSC_HOST_CALL call(ExecState*, JSObject* functionObject, JSValue thisValue, const ArgList&);
     static JSObject* construct(ExecState*, JSObject* constructor, const ArgList&);
    
     static JSValue JSC_HOST_CALL call(ExecState*, JSObject* functionObject, JSValue thisValue, const ArgList&);
     static JSObject* construct(ExecState*, JSObject* constructor, const ArgList&);
    
-    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)
-            : privateData(privateData)
-            , jsClass(jsClass)
-        {
-            JSClassRetain(jsClass);
-        }
-        
-        ~JSCallbackObjectData()
-        {
-            JSClassRelease(jsClass);
-        }
-        
-        void* privateData;
-        JSClassRef jsClass;
-    };
-    
+    static JSValue staticValueGetter(ExecState*, JSValue, const Identifier&);
+    static JSValue staticFunctionGetter(ExecState*, JSValue, const Identifier&);
+    static JSValue callbackGetter(ExecState*, JSValue, const Identifier&);
+
     OwnPtr<JSCallbackObjectData> m_callbackObjectData;
 };
 
     OwnPtr<JSCallbackObjectData> m_callbackObjectData;
 };
 
index 4b28a99285bdc2010e7d685569e9885cc403a1d2..6c83eb4e7e83385e156d06bcd58f397c85a49a90 100644 (file)
@@ -516,9 +516,9 @@ bool JSCallbackObject<Base>::inherits(JSClassRef c) const
 }
 
 template <class Base>
 }
 
 template <class Base>
-JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
 {
 {
-    JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
+    JSCallbackObject* thisObj = asCallbackObject(slotBase);
     
     JSObjectRef thisRef = toRef(thisObj);
     RefPtr<OpaqueJSString> propertyNameRef;
     
     JSObjectRef thisRef = toRef(thisObj);
     RefPtr<OpaqueJSString> propertyNameRef;
@@ -547,9 +547,9 @@ JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identif
 }
 
 template <class Base>
 }
 
 template <class Base>
-JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
 {
 {
-    JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
+    JSCallbackObject* thisObj = asCallbackObject(slotBase);
     
     // Check for cached or override property.
     PropertySlot slot2(thisObj);
     
     // Check for cached or override property.
     PropertySlot slot2(thisObj);
@@ -572,9 +572,9 @@ JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Iden
 }
 
 template <class Base>
 }
 
 template <class Base>
-JSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, const Identifier& propertyName, const PropertySlot& slot)
+JSValue JSCallbackObject<Base>::callbackGetter(ExecState* exec, JSValue slotBase, const Identifier& propertyName)
 {
 {
-    JSCallbackObject* thisObj = asCallbackObject(slot.slotBase());
+    JSCallbackObject* thisObj = asCallbackObject(slotBase);
     
     JSObjectRef thisRef = toRef(thisObj);
     RefPtr<OpaqueJSString> propertyNameRef;
     
     JSObjectRef thisRef = toRef(thisObj);
     RefPtr<OpaqueJSString> propertyNameRef;
index d75d5cdbd499b3169a61c73e652e4c3a4304c2a5..3e65b753feff3a8a31ba5e65553db028773f8e74 100644 (file)
 #include <runtime/JSGlobalObject.h>
 #include <runtime/ObjectPrototype.h>
 #include <runtime/Identifier.h>
 #include <runtime/JSGlobalObject.h>
 #include <runtime/ObjectPrototype.h>
 #include <runtime/Identifier.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/unicode/UTF8.h>
 
 using namespace std;
 using namespace JSC;
 
 using namespace std;
 using namespace JSC;
+using namespace WTF::Unicode;
 
 const JSClassDefinition kJSClassDefinitionEmpty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
 
 const JSClassDefinition kJSClassDefinitionEmpty = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
+static inline UString tryCreateStringFromUTF8(const char* string)
+{
+    if (!string)
+        return UString::null();
+
+    size_t length = strlen(string);
+    Vector<UChar, 1024> buffer(length);
+    UChar* p = buffer.data();
+    if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
+        return UString::null();
+
+    return UString(buffer.data(), p - buffer.data());
+}
+
 OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* protoClass) 
     : parentClass(definition->parentClass)
     , prototypeClass(0)
 OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass* protoClass) 
     : parentClass(definition->parentClass)
     , prototypeClass(0)
@@ -53,7 +70,7 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
     , callAsConstructor(definition->callAsConstructor)
     , hasInstance(definition->hasInstance)
     , convertToType(definition->convertToType)
     , callAsConstructor(definition->callAsConstructor)
     , hasInstance(definition->hasInstance)
     , convertToType(definition->convertToType)
-    , m_className(UString::createFromUTF8(definition->className).rep()->ref())
+    , m_className(tryCreateStringFromUTF8(definition->className))
     , m_staticValues(0)
     , m_staticFunctions(0)
 {
     , m_staticValues(0)
     , m_staticFunctions(0)
 {
@@ -62,9 +79,14 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
     if (const JSStaticValue* staticValue = definition->staticValues) {
         m_staticValues = new OpaqueJSClassStaticValuesTable();
         while (staticValue->name) {
     if (const JSStaticValue* staticValue = definition->staticValues) {
         m_staticValues = new OpaqueJSClassStaticValuesTable();
         while (staticValue->name) {
-            // Use a local variable here to sidestep an RVCT compiler bug.
-            StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes);
-            m_staticValues->add(UString::createFromUTF8(staticValue->name).rep()->ref(), entry);
+            UString valueName = tryCreateStringFromUTF8(staticValue->name);
+            if (!valueName.isNull()) {
+                // Use a local variable here to sidestep an RVCT compiler bug.
+                StaticValueEntry* entry = new StaticValueEntry(staticValue->getProperty, staticValue->setProperty, staticValue->attributes);
+                UStringImpl* impl = valueName.rep();
+                impl->ref();
+                m_staticValues->add(impl, entry);
+            }
             ++staticValue;
         }
     }
             ++staticValue;
         }
     }
@@ -72,9 +94,14 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
     if (const JSStaticFunction* staticFunction = definition->staticFunctions) {
         m_staticFunctions = new OpaqueJSClassStaticFunctionsTable();
         while (staticFunction->name) {
     if (const JSStaticFunction* staticFunction = definition->staticFunctions) {
         m_staticFunctions = new OpaqueJSClassStaticFunctionsTable();
         while (staticFunction->name) {
-            // Use a local variable here to sidestep an RVCT compiler bug.
-            StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes);
-            m_staticFunctions->add(UString::createFromUTF8(staticFunction->name).rep()->ref(), entry);
+            UString functionName = tryCreateStringFromUTF8(staticFunction->name);
+            if (!functionName.isNull()) {
+                // Use a local variable here to sidestep an RVCT compiler bug.
+                StaticFunctionEntry* entry = new StaticFunctionEntry(staticFunction->callAsFunction, staticFunction->attributes);
+                UStringImpl* impl = functionName.rep();
+                impl->ref();
+                m_staticFunctions->add(impl, entry);
+            }
             ++staticFunction;
         }
     }
             ++staticFunction;
         }
     }
@@ -85,7 +112,8 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, OpaqueJSClass*
 
 OpaqueJSClass::~OpaqueJSClass()
 {
 
 OpaqueJSClass::~OpaqueJSClass()
 {
-    ASSERT(!m_className.rep()->isIdentifier());
+    // The empty string is shared across threads & is an identifier, in all other cases we should have done a deep copy in className(), below. 
+    ASSERT(!m_className.size() || !m_className.rep()->isIdentifier());
 
     if (m_staticValues) {
         OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end();
 
     if (m_staticValues) {
         OpaqueJSClassStaticValuesTable::const_iterator end = m_staticValues->end();
@@ -145,13 +173,10 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass)
             ASSERT(!it->first->isIdentifier());
             // Use a local variable here to sidestep an RVCT compiler bug.
             StaticValueEntry* entry = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes);
             ASSERT(!it->first->isIdentifier());
             // Use a local variable here to sidestep an RVCT compiler bug.
             StaticValueEntry* entry = new StaticValueEntry(it->second->getProperty, it->second->setProperty, it->second->attributes);
-            staticValues->add(UString::Rep::create(it->first->data(), it->first->size()), entry);
-
+            staticValues->add(UString::Rep::create(it->first->characters(), it->first->length()), entry);
         }
         }
-            
     } else
         staticValues = 0;
     } else
         staticValues = 0;
-        
 
     if (jsClass->m_staticFunctions) {
         staticFunctions = new OpaqueJSClassStaticFunctionsTable;
 
     if (jsClass->m_staticFunctions) {
         staticFunctions = new OpaqueJSClassStaticFunctionsTable;
@@ -160,7 +185,7 @@ OpaqueJSClassContextData::OpaqueJSClassContextData(OpaqueJSClass* jsClass)
             ASSERT(!it->first->isIdentifier());
             // Use a local variable here to sidestep an RVCT compiler bug.
             StaticFunctionEntry* entry = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes);
             ASSERT(!it->first->isIdentifier());
             // Use a local variable here to sidestep an RVCT compiler bug.
             StaticFunctionEntry* entry = new StaticFunctionEntry(it->second->callAsFunction, it->second->attributes);
-            staticFunctions->add(UString::Rep::create(it->first->data(), it->first->size()), entry);
+            staticFunctions->add(UString::Rep::create(it->first->characters(), it->first->length()), entry);
         }
             
     } else
         }
             
     } else
index 2c763387666f0f0127557edc2d62255ba093aaba..b97ceda6799a66e823379a414421239a3c4bac2c 100644 (file)
@@ -33,7 +33,7 @@
 #include "JSClassRef.h"
 #include "JSGlobalObject.h"
 #include "JSObject.h"
 #include "JSClassRef.h"
 #include "JSGlobalObject.h"
 #include "JSObject.h"
-#include <wtf/Platform.h>
+#include <wtf/text/StringHash.h>
 
 #if OS(DARWIN)
 #include <mach-o/dyld.h>
 
 #if OS(DARWIN)
 #include <mach-o/dyld.h>
@@ -46,7 +46,7 @@ using namespace JSC;
 JSContextGroupRef JSContextGroupCreate()
 {
     initializeThreading();
 JSContextGroupRef JSContextGroupCreate()
 {
     initializeThreading();
-    return toRef(JSGlobalData::createNonDefault().releaseRef());
+    return toRef(JSGlobalData::createContextGroup(ThreadStackTypeSmall).releaseRef());
 }
 
 JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
 }
 
 JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
@@ -84,7 +84,7 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
     initializeThreading();
 
     JSLock lock(LockForReal);
     initializeThreading();
 
     JSLock lock(LockForReal);
-    RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault();
+    RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createContextGroup(ThreadStackTypeSmall);
 
     APIEntryShim entryShim(globalData.get(), false);
 
 
     APIEntryShim entryShim(globalData.get(), false);
 
@@ -123,19 +123,32 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx)
     JSLock lock(exec);
 
     JSGlobalData& globalData = exec->globalData();
     JSLock lock(exec);
 
     JSGlobalData& globalData = exec->globalData();
-    IdentifierTable* savedIdentifierTable = setCurrentIdentifierTable(globalData.identifierTable);
-
-    gcUnprotect(exec->dynamicGlobalObject());
-
-    if (globalData.refCount() == 2) { // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain().
-        // The last reference was released, this is our last chance to collect.
+    JSGlobalObject* dgo = exec->dynamicGlobalObject();
+    IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable);
+
+    // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain().
+    bool releasingContextGroup = globalData.refCount() == 2;
+    bool releasingGlobalObject = Heap::heap(dgo)->unprotect(dgo);
+    // If this is the last reference to a global data, it should also
+    // be the only remaining reference to the global object too!
+    ASSERT(!releasingContextGroup || releasingGlobalObject);
+
+    // An API 'JSGlobalContextRef' retains two things - a global object and a
+    // global data (or context group, in API terminology).
+    // * If this is the last reference to any contexts in the given context group,
+    //   call destroy on the heap (the global data is being  freed).
+    // * If this was the last reference to the global object, then unprotecting
+    //   it may  release a lot of GC memory - run the garbage collector now.
+    // * If there are more references remaining the the global object, then do nothing
+    //   (specifically that is more protects, which we assume come from other JSGlobalContextRefs).
+    if (releasingContextGroup)
         globalData.heap.destroy();
         globalData.heap.destroy();
-    } else
+    else if (releasingGlobalObject)
         globalData.heap.collectAllGarbage();
 
     globalData.deref();
 
         globalData.heap.collectAllGarbage();
 
     globalData.deref();
 
-    setCurrentIdentifierTable(savedIdentifierTable);
+    wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
 }
 
 JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
 }
 
 JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
index faaa4eb669753451ab997f20b40d81b8e55bde26..8fdbdab9059300a8af7fa22f428dd3bc0eb987d5 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "config.h"
 #include "JSObjectRef.h"
 
 #include "config.h"
 #include "JSObjectRef.h"
+#include "JSObjectRefPrivate.h"
 
 #include "APICast.h"
 #include "CodeBlock.h"
 
 #include "APICast.h"
 #include "CodeBlock.h"
@@ -48,7 +49,6 @@
 #include "ObjectPrototype.h"
 #include "PropertyNameArray.h"
 #include "RegExpConstructor.h"
 #include "ObjectPrototype.h"
 #include "PropertyNameArray.h"
 #include "RegExpConstructor.h"
-#include <wtf/Platform.h>
 
 using namespace JSC;
 
 
 using namespace JSC;
 
@@ -364,6 +364,55 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data)
     return false;
 }
 
     return false;
 }
 
+JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
+{
+    ExecState* exec = toJS(ctx);
+    APIEntryShim entryShim(exec);
+    JSObject* jsObject = toJS(object);
+    JSValue result;
+    Identifier name(propertyName->identifier(&exec->globalData()));
+    if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info))
+        result = static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->getPrivateProperty(name);
+    else if (jsObject->inherits(&JSCallbackObject<JSObject>::info))
+        result = static_cast<JSCallbackObject<JSObject>*>(jsObject)->getPrivateProperty(name);
+    return toRef(exec, result);
+}
+
+bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value)
+{
+    ExecState* exec = toJS(ctx);
+    APIEntryShim entryShim(exec);
+    JSObject* jsObject = toJS(object);
+    JSValue jsValue = toJS(exec, value);
+    Identifier name(propertyName->identifier(&exec->globalData()));
+    if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) {
+        static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->setPrivateProperty(name, jsValue);
+        return true;
+    }
+    if (jsObject->inherits(&JSCallbackObject<JSObject>::info)) {
+        static_cast<JSCallbackObject<JSObject>*>(jsObject)->setPrivateProperty(name, jsValue);
+        return true;
+    }
+    return false;
+}
+
+bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
+{
+    ExecState* exec = toJS(ctx);
+    APIEntryShim entryShim(exec);
+    JSObject* jsObject = toJS(object);
+    Identifier name(propertyName->identifier(&exec->globalData()));
+    if (jsObject->inherits(&JSCallbackObject<JSGlobalObject>::info)) {
+        static_cast<JSCallbackObject<JSGlobalObject>*>(jsObject)->deletePrivateProperty(name);
+        return true;
+    }
+    if (jsObject->inherits(&JSCallbackObject<JSObject>::info)) {
+        static_cast<JSCallbackObject<JSObject>*>(jsObject)->deletePrivateProperty(name);
+        return true;
+    }
+    return false;
+}
+
 bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
 {
     CallData callData;
 bool JSObjectIsFunction(JSContextRef, JSObjectRef object)
 {
     CallData callData;
diff --git a/API/JSObjectRefPrivate.h b/API/JSObjectRefPrivate.h
new file mode 100644 (file)
index 0000000..32e80ab
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010 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. 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 INC. 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 JSObjectRefPrivate_h
+#define JSObjectRefPrivate_h
+
+#include <JavaScriptCore/JSObjectRef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ @function
+ @abstract Sets a private property on an object.  This private property cannot be accessed from within JavaScript.
+ @param ctx The execution context to use.
+ @param object The JSObject whose private property you want to set.
+ @param propertyName A JSString containing the property's name.
+ @param value A JSValue to use as the property's value.  This may be NULL.
+ @result true if object can store private data, otherwise false.
+ @discussion This API allows you to store JS values directly an object in a way that will be ensure that they are kept alive without exposing them to JavaScript code and without introducing the reference cycles that may occur when using JSValueProtect.
+
+ The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private properties.
+ */
+JS_EXPORT bool JSObjectSetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName, JSValueRef value);
+
+/*!
+ @function
+ @abstract Gets a private property from an object.
+ @param ctx The execution context to use.
+ @param object The JSObject whose private property you want to get.
+ @param propertyName A JSString containing the property's name.
+ @result The property's value if object has the property, otherwise NULL.
+ */
+JS_EXPORT JSValueRef JSObjectGetPrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName);
+
+/*!
+ @function
+ @abstract Deletes a private property from an object.
+ @param ctx The execution context to use.
+ @param object The JSObject whose private property you want to delete.
+ @param propertyName A JSString containing the property's name.
+ @result true if object can store private data, otherwise false.
+ @discussion The default object class does not allocate storage for private data. Only objects created with a non-NULL JSClass can store private data.
+ */
+JS_EXPORT bool JSObjectDeletePrivateProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JSObjectRefPrivate_h
index c58b95821043474094fcc4fe7e9a1047b259d262..51871b121dbc5107ade79a319eed1660e704186a 100644 (file)
@@ -37,7 +37,8 @@
 extern "C" {
 #endif
 
 extern "C" {
 #endif
 
-#if !defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__)
+#if !defined(WIN32) && !defined(_WIN32) && !defined(__WINSCW__) \
+    && !((defined(__CC_ARM) || defined(__ARMCC__)) && defined(__SYMBIAN32__)) /* RVCT */
 /*!
 @typedef JSChar
 @abstract A Unicode character.
 /*!
 @typedef JSChar
 @abstract A Unicode character.
index a12cc3409a2e10dd5ef6c8986fe187e6bdf8276a..905dcbf34e4d5b0745977f7eeb36fe164bd339cb 100644 (file)
 #include "config.h"
 #include "JSValueRef.h"
 
 #include "config.h"
 #include "JSValueRef.h"
 
-#include <wtf/Platform.h>
 #include "APICast.h"
 #include "APIShims.h"
 #include "JSCallbackObject.h"
 
 #include <runtime/JSGlobalObject.h>
 #include "APICast.h"
 #include "APIShims.h"
 #include "JSCallbackObject.h"
 
 #include <runtime/JSGlobalObject.h>
+#include <runtime/JSONObject.h>
 #include <runtime/JSString.h>
 #include <runtime/JSString.h>
+#include <runtime/LiteralParser.h>
 #include <runtime/Operations.h>
 #include <runtime/Protect.h>
 #include <runtime/UString.h>
 #include <runtime/JSValue.h>
 
 #include <wtf/Assertions.h>
 #include <runtime/Operations.h>
 #include <runtime/Protect.h>
 #include <runtime/UString.h>
 #include <runtime/JSValue.h>
 
 #include <wtf/Assertions.h>
+#include <wtf/text/StringHash.h>
 
 #include <algorithm> // for std::min
 
 
 #include <algorithm> // for std::min
 
@@ -211,6 +213,12 @@ JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
     ExecState* exec = toJS(ctx);
     APIEntryShim entryShim(exec);
 
     ExecState* exec = toJS(ctx);
     APIEntryShim entryShim(exec);
 
+    // Our JSValue representation relies on a standard bit pattern for NaN. NaNs
+    // generated internally to JavaScriptCore naturally have that representation,
+    // but an external NaN might not.
+    if (isnan(value))
+        value = NaN;
+
     return toRef(exec, jsNumber(exec, value));
 }
 
     return toRef(exec, jsNumber(exec, value));
 }
 
@@ -222,6 +230,31 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
     return toRef(exec, jsString(exec, string->ustring()));
 }
 
     return toRef(exec, jsString(exec, string->ustring()));
 }
 
+JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string)
+{
+    ExecState* exec = toJS(ctx);
+    APIEntryShim entryShim(exec);
+    LiteralParser parser(exec, string->ustring(), LiteralParser::StrictJSON);
+    return toRef(exec, parser.tryLiteralParse());
+}
+
+JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef apiValue, unsigned indent, JSValueRef* exception)
+{
+    ExecState* exec = toJS(ctx);
+    APIEntryShim entryShim(exec);
+    JSValue value = toJS(exec, apiValue);
+    UString result = JSONStringify(exec, value, indent);
+    if (exception)
+        *exception = 0;
+    if (exec->hadException()) {
+        if (exception)
+            *exception = toRef(exec, exec->exception());
+        exec->clearException();
+        return 0;
+    }
+    return OpaqueJSString::create(result).releaseRef();
+}
+
 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
 {
     ExecState* exec = toJS(ctx);
 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
 {
     ExecState* exec = toJS(ctx);
index 7a7bf93a17afa3f8e5b85164fe8818c8e21d8a76..4186db822ad78f693786d4b79e0b34c02295fb44 100644 (file)
@@ -27,6 +27,7 @@
 #define JSValueRef_h
 
 #include <JavaScriptCore/JSBase.h>
 #define JSValueRef_h
 
 #include <JavaScriptCore/JSBase.h>
+#include <JavaScriptCore/WebKitAvailability.h>
 
 #ifndef __cplusplus
 #include <stdbool.h>
 
 #ifndef __cplusplus
 #include <stdbool.h>
@@ -208,6 +209,28 @@ JS_EXPORT JSValueRef JSValueMakeNumber(JSContextRef ctx, double number);
 */
 JS_EXPORT JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string);
 
 */
 JS_EXPORT JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string);
 
+/* Converting to and from JSON formatted strings */
+
+/*!
+ @function
+ @abstract       Creates a JavaScript value from a JSON formatted string.
+ @param ctx      The execution context to use.
+ @param string   The JSString containing the JSON string to be parsed.
+ @result         A JSValue containing the parsed value, or NULL if the input is invalid.
+ */
+JS_EXPORT JSValueRef JSValueMakeFromJSONString(JSContextRef ctx, JSStringRef string) AVAILABLE_AFTER_WEBKIT_VERSION_4_0;
+
+/*!
+ @function
+ @abstract       Creates a JavaScript string containing the JSON serialized representation of a JS value.
+ @param ctx      The execution context to use.
+ @param value    The value to serialize.
+ @param indent   The number of spaces to indent when nesting.  If 0, the resulting JSON will not contains newlines.  The size of the indent is clamped to 10 spaces.
+ @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 JSString with the result of serialization, or NULL if an exception is thrown.
+ */
+JS_EXPORT JSStringRef JSValueCreateJSONString(JSContextRef ctx, JSValueRef value, unsigned indent, JSValueRef* exception) AVAILABLE_AFTER_WEBKIT_VERSION_4_0;
+
 /* Converting to primitive values */
 
 /*!
 /* Converting to primitive values */
 
 /*!
diff --git a/API/JSWeakObjectMapRefInternal.h b/API/JSWeakObjectMapRefInternal.h
new file mode 100644 (file)
index 0000000..64e1f4d
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 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. 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 INC. 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 JSWeakObjectMapRefInternal_h
+#define JSWeakObjectMapRefInternal_h
+
+#include "WeakGCMap.h"
+#include <wtf/RefCounted.h>
+
+namespace JSC {
+
+class JSObject;
+
+}
+
+typedef void (*JSWeakMapDestroyedCallback)(struct OpaqueJSWeakObjectMap*, void*);
+
+typedef JSC::WeakGCMap<void*, JSC::JSObject*> WeakMapType;
+
+struct OpaqueJSWeakObjectMap : public RefCounted<OpaqueJSWeakObjectMap> {
+public:
+    static PassRefPtr<OpaqueJSWeakObjectMap> create(void* data, JSWeakMapDestroyedCallback callback)
+    {
+        return adoptRef(new OpaqueJSWeakObjectMap(data, callback));
+    }
+
+    WeakMapType& map() { return m_map; }
+    
+    ~OpaqueJSWeakObjectMap()
+    {
+        m_callback(this, m_data);
+    }
+
+private:
+    OpaqueJSWeakObjectMap(void* data, JSWeakMapDestroyedCallback callback)
+        : m_data(data)
+        , m_callback(callback)
+    {
+    }
+    WeakMapType m_map;
+    void* m_data;
+    JSWeakMapDestroyedCallback m_callback;
+};
+
+
+#endif // JSWeakObjectMapInternal_h
diff --git a/API/JSWeakObjectMapRefPrivate.cpp b/API/JSWeakObjectMapRefPrivate.cpp
new file mode 100644 (file)
index 0000000..7e6bb63
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2010 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. 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 INC. 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 "JSWeakObjectMapRefPrivate.h"
+
+#include "APICast.h"
+#include "APIShims.h"
+#include "JSCallbackObject.h"
+#include "JSValue.h"
+#include "JSWeakObjectMapRefInternal.h"
+#include <wtf/HashMap.h>
+#include <wtf/RefCounted.h>
+#include <wtf/text/StringHash.h>
+
+using namespace WTF;
+using namespace JSC;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef context, void* privateData, JSWeakMapDestroyedCallback callback)
+{
+    ExecState* exec = toJS(context);
+    APIEntryShim entryShim(exec);
+    RefPtr<OpaqueJSWeakObjectMap> map = OpaqueJSWeakObjectMap::create(privateData, callback);
+    exec->lexicalGlobalObject()->registerWeakMap(map.get());
+    return map.get();
+}
+
+void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object)
+{
+    ExecState* exec = toJS(ctx);
+    APIEntryShim entryShim(exec);
+    JSObject* obj = toJS(object);
+    if (!obj)
+        return;
+    ASSERT(obj->inherits(&JSCallbackObject<JSGlobalObject>::info) || obj->inherits(&JSCallbackObject<JSObject>::info));
+    map->map().set(key, obj);
+}
+
+JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* key)
+{
+    ExecState* exec = toJS(ctx);
+    APIEntryShim entryShim(exec);
+    return toRef(static_cast<JSObject*>(map->map().get(key)));
+}
+
+bool JSWeakObjectMapClear(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object)
+{
+    ExecState* exec = toJS(ctx);
+    APIEntryShim entryShim(exec);
+    JSObject* obj = toJS(object);
+    if (map->map().uncheckedRemove(key, obj))
+        return true;
+    return false;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/API/JSWeakObjectMapRefPrivate.h b/API/JSWeakObjectMapRefPrivate.h
new file mode 100644 (file)
index 0000000..d36111c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 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. 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 INC. 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 JSWeakObjectMapRefPrivate_h
+#define JSWeakObjectMapRefPrivate_h
+
+#include <JavaScriptCore/JSContextRef.h>
+#include <JavaScriptCore/JSValueRef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+    
+/*! @typedef JSWeakObjectMapRef A weak map for storing JSObjectRefs */
+typedef struct OpaqueJSWeakObjectMap* JSWeakObjectMapRef;
+
+/*! 
+ @typedef JSWeakMapDestroyedCallback
+ @abstract The callback invoked when a JSWeakObjectMapRef is being destroyed.
+ @param map The map that is being destroyed.
+ @param data The private data (if any) that was associated with the map instance.
+ */
+typedef void (*JSWeakMapDestroyedCallback)(JSWeakObjectMapRef map, void* data);
+
+/*!
+ @function
+ @abstract Creates a weak value map that can be used to reference user defined objects without preventing them from being collected.
+ @param ctx The execution context to use.
+ @param data A void* to set as the map's private data. Pass NULL to specify no private data.
+ @param destructor A function to call when the weak map is destroyed.
+ @result A JSWeakObjectMapRef bound to the given context, data and destructor.
+ @discussion The JSWeakObjectMapRef can be used as a storage mechanism to hold custom JS objects without forcing those objects to
+ remain live as JSValueProtect would.  Any objects that are intended to be stored in a weak map must be user defined objects that
+ remove themselves from the map in their finalizer.
+ */
+JS_EXPORT JSWeakObjectMapRef JSWeakObjectMapCreate(JSContextRef ctx, void* data, JSWeakMapDestroyedCallback destructor);
+
+/*!
+ @function
+ @abstract Associates a JSObjectRef with the given key in a JSWeakObjectMap.
+ @param ctx The execution context to use.
+ @param map The map to operate on.
+ @param key The key to associate a weak reference with.
+ @param object The user defined object to associate with the key.
+ */
+JS_EXPORT void JSWeakObjectMapSet(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef);
+
+/*!
+ @function
+ @abstract Retrieves the JSObjectRef associated with a key.
+ @param ctx The execution context to use.
+ @param map The map to query.
+ @param key The key to search for.
+ @result Either the live object associated with the provided key, or NULL.
+ */
+JS_EXPORT JSObjectRef JSWeakObjectMapGet(JSContextRef ctx, JSWeakObjectMapRef map, void* key);
+
+/*!
+ @function
+ @abstract Clears the association between a key and an object in a JSWeakObjectMapRef
+ @param ctx The execution context to use.
+ @param map The map to clear the key association from.
+ @param key The key to use.
+ @param object The old object value.
+ @result Returns true if the key/object association was present in map, and has been removed.
+ */
+JS_EXPORT bool JSWeakObjectMapClear(JSContextRef ctx, JSWeakObjectMapRef map, void* key, JSObjectRef object);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JSWeakObjectMapPrivate_h
index 8402528317a920ac270dff409206a7d7b60f11d7..0e4f091cc79991c0959ca6c7e080b40eeb79ab0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2009, 2010 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,7 +42,7 @@
 #define WEBKIT_VERSION_LATEST 0x9999
 
 #ifdef __APPLE__
 #define WEBKIT_VERSION_LATEST 0x9999
 
 #ifdef __APPLE__
-#import <AvailabilityMacros.h>
+#include <AvailabilityMacros.h>
 #else
 /*
  * For non-Mac platforms, require the newest version.
 #else
 /*
  * For non-Mac platforms, require the newest version.
@@ -86,6 +86,9 @@
     #elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
         /* WebKit 3.0 is the version that shipped on Mac OS X 10.5. */
         #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_3_0
     #elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6
         /* WebKit 3.0 is the version that shipped on Mac OS X 10.5. */
         #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_3_0
+    #elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
+        /* WebKit 4.0 is the version that shipped on Mac OS X 10.6. */
+        #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_4_0
     #else
         #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_LATEST
     #endif
     #else
         #define WEBKIT_VERSION_MIN_REQUIRED WEBKIT_VERSION_LATEST
     #endif
  * 
  * Used on declarations introduced in WebKit 4.0
  */
  * 
  * Used on declarations introduced in WebKit 4.0
  */
-#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_4_0
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0     UNAVAILABLE_ATTRIBUTE
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0     UNAVAILABLE_ATTRIBUTE
-#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_LATEST
+#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_4_0
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0     WEAK_IMPORT_ATTRIBUTE
 #else
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0     WEAK_IMPORT_ATTRIBUTE
 #else
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0
  * Used on declarations introduced in WebKit 4.0, 
  * and deprecated in WebKit 4.0
  */
  * Used on declarations introduced in WebKit 4.0, 
  * and deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED    DEPRECATED_ATTRIBUTE
 #else
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED    AVAILABLE_IN_WEBKIT_VERSION_4_0
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED    DEPRECATED_ATTRIBUTE
 #else
     #define AVAILABLE_IN_WEBKIT_VERSION_4_0_BUT_DEPRECATED    AVAILABLE_IN_WEBKIT_VERSION_4_0
  * Used on declarations introduced in WebKit 1.0, 
  * but later deprecated in WebKit 4.0
  */
  * Used on declarations introduced in WebKit 1.0, 
  * but later deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
  * Used on declarations introduced in WebKit 1.1, 
  * but later deprecated in WebKit 4.0
  */
  * Used on declarations introduced in WebKit 1.1, 
  * but later deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
  * Used on declarations introduced in WebKit 1.2, 
  * but later deprecated in WebKit 4.0
  */
  * Used on declarations introduced in WebKit 1.2, 
  * but later deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
  * Used on declarations introduced in WebKit 1.3, 
  * but later deprecated in WebKit 4.0
  */
  * Used on declarations introduced in WebKit 1.3, 
  * but later deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
  * Used on declarations introduced in WebKit 2.0, 
  * but later deprecated in WebKit 4.0
  */
  * Used on declarations introduced in WebKit 2.0, 
  * but later deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
  * Used on declarations introduced in WebKit 3.0, 
  * but later deprecated in WebKit 4.0
  */
  * Used on declarations introduced in WebKit 3.0, 
  * but later deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
  * Used on declarations introduced in WebKit 3.1, 
  * but later deprecated in WebKit 4.0
  */
  * Used on declarations introduced in WebKit 3.1, 
  * but later deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
     #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_IN_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
  * 
  * Used on types deprecated in WebKit 4.0
  */
  * 
  * Used on types deprecated in WebKit 4.0
  */
-#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_4_0
     #define DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
     #define DEPRECATED_IN_WEBKIT_VERSION_4_0
 #endif
 
 
     #define DEPRECATED_IN_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
 #else
     #define DEPRECATED_IN_WEBKIT_VERSION_4_0
 #endif
 
 
+
+
+
+
+/*
+ * AVAILABLE_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MAX_ALLOWED < WEBKIT_VERSION_LATEST
+    #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0     UNAVAILABLE_ATTRIBUTE
+#elif WEBKIT_VERSION_MIN_REQUIRED < WEBKIT_VERSION_LATEST
+    #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0     WEAK_IMPORT_ATTRIBUTE
+#else
+    #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0
+#endif
+
+/*
+ * AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED
+ * 
+ * Used on declarations introduced after WebKit 4.0, 
+ * and deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_AFTER_WEBKIT_VERSION_4_0_BUT_DEPRECATED    AVAILABLE_AFTER_WEBKIT_VERSION_4_0
+#endif
+
+/*
+ * AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced in WebKit 1.0, 
+ * but later deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_0_AND_LATER
+#endif
+
+/*
+ * AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced in WebKit 1.1, 
+ * but later deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_1_AND_LATER
+#endif
+
+/*
+ * AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced in WebKit 1.2, 
+ * but later deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_2_AND_LATER
+#endif
+
+/*
+ * AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced in WebKit 1.3, 
+ * but later deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER
+#endif
+
+/*
+ * AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced in WebKit 2.0, 
+ * but later deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_2_0_AND_LATER
+#endif
+
+/*
+ * AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced in WebKit 3.0, 
+ * but later deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_3_0_AND_LATER
+#endif
+
+/*
+ * AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced in WebKit 3.1, 
+ * but later deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_3_1_AND_LATER
+#endif
+
+/*
+ * AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on declarations introduced in WebKit 4.0 
+ * but later deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_4_0    AVAILABLE_WEBKIT_VERSION_4_0_AND_LATER
+#endif
+
+/*
+ * DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+ * 
+ * Used on types deprecated after WebKit 4.0
+ */
+#if WEBKIT_VERSION_MIN_REQUIRED >= WEBKIT_VERSION_LATEST
+    #define DEPRECATED_AFTER_WEBKIT_VERSION_4_0    DEPRECATED_ATTRIBUTE
+#else
+    #define DEPRECATED_AFTER_WEBKIT_VERSION_4_0
+#endif
+
+
 #endif /* __WebKitAvailability__ */
 #endif /* __WebKitAvailability__ */
index ebc0cfb64d7d73afa086dbb546eacb5a9f156409..28b4ec8137fcb0eff0c0c0d52772333eeac51aec 100644 (file)
@@ -26,6 +26,7 @@
 #include "JavaScriptCore.h"
 #include "JSBasePrivate.h"
 #include "JSContextRefPrivate.h"
 #include "JavaScriptCore.h"
 #include "JSBasePrivate.h"
 #include "JSContextRefPrivate.h"
+#include "JSObjectRefPrivate.h"
 #include <math.h>
 #define ASSERT_DISABLED 0
 #include <wtf/Assertions.h>
 #include <math.h>
 #define ASSERT_DISABLED 0
 #include <wtf/Assertions.h>
@@ -754,6 +755,8 @@ static void testInitializeFinalize()
 
 static JSValueRef jsNumberValue =  NULL;
 
 
 static JSValueRef jsNumberValue =  NULL;
 
+static JSObjectRef aHeapRef = NULL;
+
 static void makeGlobalNumberValue(JSContextRef context) {
     JSValueRef v = JSValueMakeNumber(context, 420);
     JSValueProtect(context, v);
 static void makeGlobalNumberValue(JSContextRef context) {
     JSValueRef v = JSValueMakeNumber(context, 420);
     JSValueProtect(context, v);
@@ -870,8 +873,107 @@ int main(int argc, char* argv[])
     JSObjectSetProperty(context, globalObject, EmptyObjectIString, EmptyObject, kJSPropertyAttributeNone, NULL);
     JSStringRelease(EmptyObjectIString);
     
     JSObjectSetProperty(context, globalObject, EmptyObjectIString, EmptyObject, kJSPropertyAttributeNone, NULL);
     JSStringRelease(EmptyObjectIString);
     
+    JSStringRef lengthStr = JSStringCreateWithUTF8CString("length");
+    aHeapRef = JSObjectMakeArray(context, 0, 0, 0);
+    JSObjectSetProperty(context, aHeapRef, lengthStr, JSValueMakeNumber(context, 10), 0, 0);
+    JSStringRef privatePropertyName = JSStringCreateWithUTF8CString("privateProperty");
+    if (!JSObjectSetPrivateProperty(context, myObject, privatePropertyName, aHeapRef)) {
+        printf("FAIL: Could not set private property.\n");
+        failed = 1;        
+    } else {
+        printf("PASS: Set private property.\n");
+    }
+    if (JSObjectSetPrivateProperty(context, aHeapRef, privatePropertyName, aHeapRef)) {
+        printf("FAIL: JSObjectSetPrivateProperty should fail on non-API objects.\n");
+        failed = 1;        
+    } else {
+        printf("PASS: Did not allow JSObjectSetPrivateProperty on a non-API object.\n");
+    }
+    if (JSObjectGetPrivateProperty(context, myObject, privatePropertyName) != aHeapRef) {
+        printf("FAIL: Could not retrieve private property.\n");
+        failed = 1;
+    } else
+        printf("PASS: Retrieved private property.\n");
+    if (JSObjectGetPrivateProperty(context, aHeapRef, privatePropertyName)) {
+        printf("FAIL: JSObjectGetPrivateProperty should return NULL when called on a non-API object.\n");
+        failed = 1;
+    } else
+        printf("PASS: JSObjectGetPrivateProperty return NULL.\n");
+    
+    if (JSObjectGetProperty(context, myObject, privatePropertyName, 0) == aHeapRef) {
+        printf("FAIL: Accessed private property through ordinary property lookup.\n");
+        failed = 1;
+    } else
+        printf("PASS: Cannot access private property through ordinary property lookup.\n");
+    
+    JSGarbageCollect(context);
+    
+    for (int i = 0; i < 10000; i++)
+        JSObjectMake(context, 0, 0);
+
+    if (JSValueToNumber(context, JSObjectGetProperty(context, aHeapRef, lengthStr, 0), 0) != 10) {
+        printf("FAIL: Private property has been collected.\n");
+        failed = 1;
+    } else
+        printf("PASS: Private property does not appear to have been collected.\n");
+    JSStringRelease(lengthStr);
+    
+    JSStringRef validJSON = JSStringCreateWithUTF8CString("{\"aProperty\":true}");
+    JSValueRef jsonObject = JSValueMakeFromJSONString(context, validJSON);
+    JSStringRelease(validJSON);
+    if (!JSValueIsObject(context, jsonObject)) {
+        printf("FAIL: Did not parse valid JSON correctly\n");
+        failed = 1;
+    } else
+        printf("PASS: Parsed valid JSON string.\n");
+    JSStringRef propertyName = JSStringCreateWithUTF8CString("aProperty");
+    assertEqualsAsBoolean(JSObjectGetProperty(context, JSValueToObject(context, jsonObject, 0), propertyName, 0), true);
+    JSStringRelease(propertyName);
+    JSStringRef invalidJSON = JSStringCreateWithUTF8CString("fail!");
+    if (JSValueMakeFromJSONString(context, invalidJSON)) {
+        printf("FAIL: Should return null for invalid JSON data\n");
+        failed = 1;
+    } else
+        printf("PASS: Correctly returned null for invalid JSON data.\n");
     JSValueRef exception;
     JSValueRef exception;
+    JSStringRef str = JSValueCreateJSONString(context, jsonObject, 0, 0);
+    if (!JSStringIsEqualToUTF8CString(str, "{\"aProperty\":true}")) {
+        printf("FAIL: Did not correctly serialise with indent of 0.\n");
+        failed = 1;
+    } else
+        printf("PASS: Correctly serialised with indent of 0.\n");
+    JSStringRelease(str);
 
 
+    str = JSValueCreateJSONString(context, jsonObject, 4, 0);
+    if (!JSStringIsEqualToUTF8CString(str, "{\n    \"aProperty\": true\n}")) {
+        printf("FAIL: Did not correctly serialise with indent of 4.\n");
+        failed = 1;
+    } else
+        printf("PASS: Correctly serialised with indent of 4.\n");
+    JSStringRelease(str);
+    JSStringRef src = JSStringCreateWithUTF8CString("({get a(){ throw '';}})");
+    JSValueRef unstringifiableObj = JSEvaluateScript(context, src, NULL, NULL, 1, NULL);
+    
+    str = JSValueCreateJSONString(context, unstringifiableObj, 4, 0);
+    if (str) {
+        printf("FAIL: Didn't return null when attempting to serialize unserializable value.\n");
+        JSStringRelease(str);
+        failed = 1;
+    } else
+        printf("PASS: returned null when attempting to serialize unserializable value.\n");
+    
+    str = JSValueCreateJSONString(context, unstringifiableObj, 4, &exception);
+    if (str) {
+        printf("FAIL: Didn't return null when attempting to serialize unserializable value.\n");
+        JSStringRelease(str);
+        failed = 1;
+    } else
+        printf("PASS: returned null when attempting to serialize unserializable value.\n");
+    if (!exception) {
+        printf("FAIL: Did not set exception on serialisation error\n");
+        failed = 1;
+    } else
+        printf("PASS: set exception on serialisation error\n");
     // Conversions that throw exceptions
     exception = NULL;
     ASSERT(NULL == JSValueToObject(context, jsNull, &exception));
     // Conversions that throw exceptions
     exception = NULL;
     ASSERT(NULL == JSValueToObject(context, jsNull, &exception));
index e76da3241824600f4af4e9290d2c1f7d07fe782e..1b5da02f16f0644bd8ded365aef45d9a5cd072ca 100644 (file)
@@ -45,6 +45,16 @@ LOCAL_SRC_FILES := \
        interpreter/Interpreter.cpp \
        interpreter/RegisterFile.cpp \
        \
        interpreter/Interpreter.cpp \
        interpreter/RegisterFile.cpp \
        \
+       jit/ExecutableAllocator.cpp\
+       jit/ExecutableAllocatorFixedVMPool.cpp \
+       jit/ExecutableAllocatorPosix.cpp \
+       jit/JIT.cpp \
+       jit/JITArithmetic.cpp \
+       jit/JITCall.cpp \
+       jit/JITOpcodes.cpp \
+       jit/JITPropertyAccess.cpp \
+       jit/JITStubs.cpp \
+       \
        parser/Lexer.cpp \
        parser/Nodes.cpp \
        parser/Parser.cpp \
        parser/Lexer.cpp \
        parser/Nodes.cpp \
        parser/Parser.cpp \
@@ -142,13 +152,6 @@ LOCAL_SRC_FILES := \
        runtime/TimeoutChecker.cpp \
        runtime/UString.cpp \
        \
        runtime/TimeoutChecker.cpp \
        runtime/UString.cpp \
        \
-       wrec/CharacterClass.cpp \
-       wrec/CharacterClassConstructor.cpp \
-       wrec/WREC.cpp \
-       wrec/WRECFunctors.cpp \
-       wrec/WRECGenerator.cpp \
-       wrec/WRECParser.cpp \
-       \
        wtf/Assertions.cpp \
        wtf/ByteArray.cpp \
        wtf/CurrentTime.cpp \
        wtf/Assertions.cpp \
        wtf/ByteArray.cpp \
        wtf/CurrentTime.cpp \
@@ -162,16 +165,26 @@ LOCAL_SRC_FILES := \
        wtf/ThreadIdentifierDataPthreads.cpp \
        wtf/Threading.cpp \
        wtf/ThreadingPthreads.cpp \
        wtf/ThreadIdentifierDataPthreads.cpp \
        wtf/Threading.cpp \
        wtf/ThreadingPthreads.cpp \
+       wtf/WTFThreadData.cpp \
        \
        wtf/TypeTraits.cpp \
        wtf/dtoa.cpp \
        \
        wtf/android/MainThreadAndroid.cpp \
        \
        \
        wtf/TypeTraits.cpp \
        wtf/dtoa.cpp \
        \
        wtf/android/MainThreadAndroid.cpp \
        \
+       wtf/text/AtomicString.cpp \
+       wtf/text/CString.cpp \
+       wtf/text/StringImpl.cpp \
+       wtf/text/WTFString.cpp \
+       \
        wtf/unicode/CollatorDefault.cpp \
        wtf/unicode/UTF8.cpp \
        \
        wtf/unicode/CollatorDefault.cpp \
        wtf/unicode/UTF8.cpp \
        \
-       wtf/unicode/icu/CollatorICU.cpp
+       wtf/unicode/icu/CollatorICU.cpp \
+       \
+       yarr/RegexCompiler.cpp \
+       yarr/RegexInterpreter.cpp \
+       yarr/RegexJIT.cpp
 
 # Rule to build grammar.y with our custom bison.
 GEN := $(intermediates)/parser/Grammar.cpp
 
 # Rule to build grammar.y with our custom bison.
 GEN := $(intermediates)/parser/Grammar.cpp
index 69128d636ddea7a35e2cf4bf1db76c8d1caa3f1b..9249e4715bf8d85ca4ac16d1bb3fd16563046368 100644 (file)
@@ -45,12 +45,18 @@ LOCAL_SRC_FILES := \
        wtf/ThreadIdentifierDataPthreads.cpp \
        wtf/Threading.cpp \
        wtf/ThreadingPthreads.cpp \
        wtf/ThreadIdentifierDataPthreads.cpp \
        wtf/Threading.cpp \
        wtf/ThreadingPthreads.cpp \
-       \
-       wtf/android/MainThreadAndroid.cpp \
+       wtf/WTFThreadData.cpp \
        \
        wtf/TypeTraits.cpp \
        wtf/dtoa.cpp \
        \
        \
        wtf/TypeTraits.cpp \
        wtf/dtoa.cpp \
        \
+       wtf/android/MainThreadAndroid.cpp \
+       \
+       wtf/text/AtomicString.cpp \
+       wtf/text/CString.cpp \
+       wtf/text/StringImpl.cpp \
+       wtf/text/WTFString.cpp \
+       \
        wtf/unicode/CollatorDefault.cpp \
        wtf/unicode/UTF8.cpp \
        \
        wtf/unicode/CollatorDefault.cpp \
        wtf/unicode/UTF8.cpp \
        \
index 9eaccab4b5bd59f5c74be13c8dc93c2848172e5b..4fc9cad1e732a6e079597db63ba4fa66b968c72a 100644 (file)
@@ -48,6 +48,7 @@ all : \
     RegExpObject.lut.h \
     StringPrototype.lut.h \
     docs/bytecode.html \
     RegExpObject.lut.h \
     StringPrototype.lut.h \
     docs/bytecode.html \
+    RegExpJitTables.h \
 #
 
 # lookup tables for classes
 #
 
 # lookup tables for classes
@@ -74,3 +75,7 @@ chartables.c : dftables
 
 docs/bytecode.html: make-bytecode-docs.pl Interpreter.cpp 
        perl $^ $@
 
 docs/bytecode.html: make-bytecode-docs.pl Interpreter.cpp 
        perl $^ $@
+
+#character tables for Yarr
+RegExpJitTables.h: create_regex_tables
+       python $^ > $@
index bd9f6abade6f4e10013be0783d29d833b2a9e115..7c5aad8de3bd090973d8853f82e16cb1f949ee99 100644 (file)
@@ -77,8 +77,8 @@ addExtraCompiler(jscbison)
 
 # GENERATOR 3: JIT Stub functions for RVCT
 rvctstubs.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Generated${QMAKE_FILE_BASE}_RVCT.h
 
 # GENERATOR 3: JIT Stub functions for RVCT
 rvctstubs.output = $${JSC_GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}Generated${QMAKE_FILE_BASE}_RVCT.h
-rvctstubs.wkScript = $$PWD/create_rvct_stubs
-rvctstubs.commands = perl $$rvctstubs.wkScript ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
+rvctstubs.wkScript = $$PWD/create_jit_stubs
+rvctstubs.commands = perl -i $$rvctstubs.wkScript --prefix RVCT ${QMAKE_FILE_NAME} > ${QMAKE_FILE_OUT}
 rvctstubs.depends = ${QMAKE_FILE_NAME}
 rvctstubs.input = RVCT_STUB_FILES
 rvctstubs.CONFIG += no_link
 rvctstubs.depends = ${QMAKE_FILE_NAME}
 rvctstubs.input = RVCT_STUB_FILES
 rvctstubs.CONFIG += no_link
@@ -93,3 +93,9 @@ ctgen.commands = perl $$ctgen.wkScript ${QMAKE_FILE_OUT} $$PREPROCESSOR
 ctgen.clean = ${QMAKE_FILE_OUT} ${QMAKE_VAR_JSC_GENERATED_SOURCES_DIR}${QMAKE_FILE_BASE}
 addExtraCompiler(ctgen)
 
 ctgen.clean = ${QMAKE_FILE_OUT} ${QMAKE_VAR_JSC_GENERATED_SOURCES_DIR}${QMAKE_FILE_BASE}
 addExtraCompiler(ctgen)
 
+#GENERATOR: "RegExpJitTables.h": tables used by Yarr
+retgen.output = $$JSC_GENERATED_SOURCES_DIR/RegExpJitTables.h
+retgen.wkScript = $$PWD/create_regex_tables 
+retgen.input = retgen.wkScript
+retgen.commands = python $$retgen.wkScript > ${QMAKE_FILE_OUT}
+addExtraCompiler(retgen)
index 7ac6a8ca8b8d38955603c5808bcfca0890ff9ec8..cd93c1bc378b465d9d43678ac0858e42be1526ef 100644 (file)
@@ -10,11 +10,13 @@ javascriptcore_cppflags += \
        -I$(srcdir)/JavaScriptCore/pcre \
        -I$(srcdir)/JavaScriptCore/profiler \
        -I$(srcdir)/JavaScriptCore/runtime \
        -I$(srcdir)/JavaScriptCore/pcre \
        -I$(srcdir)/JavaScriptCore/profiler \
        -I$(srcdir)/JavaScriptCore/runtime \
-       -I$(srcdir)/JavaScriptCore/wrec \
        -I$(srcdir)/JavaScriptCore/jit \
        -I$(srcdir)/JavaScriptCore/assembler \
        -I$(srcdir)/JavaScriptCore/jit \
        -I$(srcdir)/JavaScriptCore/assembler \
+       -I$(srcdir)/JavaScriptCore/wtf \
+       -I$(srcdir)/JavaScriptCore/wtf/text \
        -I$(srcdir)/JavaScriptCore/wtf/unicode \
        -I$(srcdir)/JavaScriptCore/yarr \
        -I$(srcdir)/JavaScriptCore/wtf/unicode \
        -I$(srcdir)/JavaScriptCore/yarr \
+       -I$(top_builddir)/JavaScriptCore \
        -I$(top_builddir)/JavaScriptCore/pcre \
        -I$(top_builddir)/JavaScriptCore/parser \
        -I$(top_builddir)/JavaScriptCore/runtime
        -I$(top_builddir)/JavaScriptCore/pcre \
        -I$(top_builddir)/JavaScriptCore/parser \
        -I$(top_builddir)/JavaScriptCore/runtime
@@ -33,6 +35,7 @@ javascriptcore_h_api += \
 
 javascriptcore_built_nosources += \
        DerivedSources/Lexer.lut.h \
 
 javascriptcore_built_nosources += \
        DerivedSources/Lexer.lut.h \
+       JavaScriptCore/RegExpJitTables.h \
        JavaScriptCore/runtime/ArrayPrototype.lut.h \
        JavaScriptCore/runtime/DatePrototype.lut.h \
        JavaScriptCore/runtime/JSONObject.lut.h \
        JavaScriptCore/runtime/ArrayPrototype.lut.h \
        JavaScriptCore/runtime/DatePrototype.lut.h \
        JavaScriptCore/runtime/JSONObject.lut.h \
@@ -81,16 +84,23 @@ javascriptcore_sources += \
        JavaScriptCore/jit/ExecutableAllocator.h \
        JavaScriptCore/jit/JIT.cpp \
        JavaScriptCore/jit/JITOpcodes.cpp \
        JavaScriptCore/jit/ExecutableAllocator.h \
        JavaScriptCore/jit/JIT.cpp \
        JavaScriptCore/jit/JITOpcodes.cpp \
+       JavaScriptCore/jit/JITOpcodes32_64.cpp \
        JavaScriptCore/jit/JITCall.cpp \
        JavaScriptCore/jit/JITCode.h \
        JavaScriptCore/jit/JITPropertyAccess.cpp \
        JavaScriptCore/jit/JITCall.cpp \
        JavaScriptCore/jit/JITCode.h \
        JavaScriptCore/jit/JITPropertyAccess.cpp \
+       JavaScriptCore/jit/JITPropertyAccess32_64.cpp \
        JavaScriptCore/jit/JITArithmetic.cpp \
        JavaScriptCore/jit/JITArithmetic.cpp \
+       JavaScriptCore/jit/JITArithmetic32_64.cpp \
        JavaScriptCore/jit/ExecutableAllocator.cpp \
        JavaScriptCore/jit/JIT.h \
        JavaScriptCore/jit/JITInlineMethods.h \
        JavaScriptCore/jit/JITStubs.cpp \
        JavaScriptCore/jit/JITStubs.h \
        JavaScriptCore/jit/JITStubCall.h \
        JavaScriptCore/jit/ExecutableAllocator.cpp \
        JavaScriptCore/jit/JIT.h \
        JavaScriptCore/jit/JITInlineMethods.h \
        JavaScriptCore/jit/JITStubs.cpp \
        JavaScriptCore/jit/JITStubs.h \
        JavaScriptCore/jit/JITStubCall.h \
+       JavaScriptCore/jit/JSInterfaceJIT.h \
+       JavaScriptCore/jit/SpecializedThunkJIT.h \
+       JavaScriptCore/jit/ThunkGenerators.cpp \
+       JavaScriptCore/jit/ThunkGenerators.h \
        JavaScriptCore/bytecode/StructureStubInfo.cpp \
        JavaScriptCore/bytecode/StructureStubInfo.h \
        JavaScriptCore/bytecode/CodeBlock.cpp \
        JavaScriptCore/bytecode/StructureStubInfo.cpp \
        JavaScriptCore/bytecode/StructureStubInfo.h \
        JavaScriptCore/bytecode/CodeBlock.cpp \
@@ -192,6 +202,7 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/JSONObject.h \
        JavaScriptCore/runtime/JSPropertyNameIterator.cpp \
        JavaScriptCore/runtime/JSPropertyNameIterator.h \
        JavaScriptCore/runtime/JSONObject.h \
        JavaScriptCore/runtime/JSPropertyNameIterator.cpp \
        JavaScriptCore/runtime/JSPropertyNameIterator.h \
+       JavaScriptCore/runtime/JSStringBuilder.h \
        JavaScriptCore/runtime/JSZombie.h \
        JavaScriptCore/runtime/LiteralParser.cpp \
        JavaScriptCore/runtime/LiteralParser.h \
        JavaScriptCore/runtime/JSZombie.h \
        JavaScriptCore/runtime/LiteralParser.cpp \
        JavaScriptCore/runtime/LiteralParser.h \
@@ -208,24 +219,18 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/StructureChain.cpp \
        JavaScriptCore/runtime/StructureChain.h \
        JavaScriptCore/runtime/StructureTransitionTable.h \
        JavaScriptCore/runtime/StructureChain.cpp \
        JavaScriptCore/runtime/StructureChain.h \
        JavaScriptCore/runtime/StructureTransitionTable.h \
+       JavaScriptCore/runtime/Terminator.h \
        JavaScriptCore/runtime/TimeoutChecker.cpp \
        JavaScriptCore/runtime/TimeoutChecker.h \
        JavaScriptCore/runtime/JSTypeInfo.h \
        JavaScriptCore/runtime/WeakGCMap.h \
        JavaScriptCore/runtime/WeakGCPtr.h \
        JavaScriptCore/runtime/TimeoutChecker.cpp \
        JavaScriptCore/runtime/TimeoutChecker.h \
        JavaScriptCore/runtime/JSTypeInfo.h \
        JavaScriptCore/runtime/WeakGCMap.h \
        JavaScriptCore/runtime/WeakGCPtr.h \
-       JavaScriptCore/wrec/CharacterClass.h \
-       JavaScriptCore/wrec/CharacterClassConstructor.h \
-       JavaScriptCore/wrec/Escapes.h \
-       JavaScriptCore/wrec/Quantifier.h \
-       JavaScriptCore/wrec/WREC.h \
-       JavaScriptCore/wrec/WRECFunctors.h \
-       JavaScriptCore/wrec/WRECGenerator.h \
-       JavaScriptCore/wrec/WRECParser.h \
        JavaScriptCore/wtf/ASCIICType.h \
        JavaScriptCore/wtf/AVLTree.h \
        JavaScriptCore/wtf/AlwaysInline.h \
        JavaScriptCore/wtf/Assertions.cpp \
        JavaScriptCore/wtf/Assertions.h \
        JavaScriptCore/wtf/ASCIICType.h \
        JavaScriptCore/wtf/AVLTree.h \
        JavaScriptCore/wtf/AlwaysInline.h \
        JavaScriptCore/wtf/Assertions.cpp \
        JavaScriptCore/wtf/Assertions.h \
+       JavaScriptCore/wtf/Atomics.h \
        JavaScriptCore/wtf/ByteArray.cpp \
        JavaScriptCore/wtf/ByteArray.h \
        JavaScriptCore/wtf/CrossThreadRefCounted.h \
        JavaScriptCore/wtf/ByteArray.cpp \
        JavaScriptCore/wtf/ByteArray.h \
        JavaScriptCore/wtf/CrossThreadRefCounted.h \
@@ -248,6 +253,8 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/ListHashSet.h \
        JavaScriptCore/wtf/ListRefPtr.h \
        JavaScriptCore/wtf/Locker.h \
        JavaScriptCore/wtf/ListHashSet.h \
        JavaScriptCore/wtf/ListRefPtr.h \
        JavaScriptCore/wtf/Locker.h \
+       JavaScriptCore/wtf/MD5.cpp \
+       JavaScriptCore/wtf/MD5.h \
        JavaScriptCore/wtf/MainThread.cpp \
        JavaScriptCore/wtf/MainThread.h \
        JavaScriptCore/wtf/MathExtras.h \
        JavaScriptCore/wtf/MainThread.cpp \
        JavaScriptCore/wtf/MainThread.h \
        JavaScriptCore/wtf/MathExtras.h \
@@ -262,7 +269,6 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/PassRefPtr.h \
        JavaScriptCore/wtf/Platform.h \
        JavaScriptCore/wtf/PossiblyNull.h \
        JavaScriptCore/wtf/PassRefPtr.h \
        JavaScriptCore/wtf/Platform.h \
        JavaScriptCore/wtf/PossiblyNull.h \
-       JavaScriptCore/wtf/PtrAndFlags.h \
        JavaScriptCore/wtf/RandomNumber.cpp \
        JavaScriptCore/wtf/RandomNumber.h \
        JavaScriptCore/wtf/RandomNumberSeed.h \
        JavaScriptCore/wtf/RandomNumber.cpp \
        JavaScriptCore/wtf/RandomNumber.h \
        JavaScriptCore/wtf/RandomNumberSeed.h \
@@ -273,6 +279,7 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/RefPtrHashMap.h \
        JavaScriptCore/wtf/RetainPtr.h \
        JavaScriptCore/wtf/SegmentedVector.h \
        JavaScriptCore/wtf/RefPtrHashMap.h \
        JavaScriptCore/wtf/RetainPtr.h \
        JavaScriptCore/wtf/SegmentedVector.h \
+       JavaScriptCore/wtf/StaticConstructors.h \
        JavaScriptCore/wtf/StdLibExtras.h \
        JavaScriptCore/wtf/StringExtras.h \
        JavaScriptCore/wtf/StringHashFunctions.h \
        JavaScriptCore/wtf/StdLibExtras.h \
        JavaScriptCore/wtf/StringExtras.h \
        JavaScriptCore/wtf/StringHashFunctions.h \
@@ -283,19 +290,35 @@ javascriptcore_sources += \
        JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h \
        JavaScriptCore/wtf/Threading.cpp \
        JavaScriptCore/wtf/Threading.h \
        JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h \
        JavaScriptCore/wtf/Threading.cpp \
        JavaScriptCore/wtf/Threading.h \
+       JavaScriptCore/wtf/ThreadingPrimitives.h \
        JavaScriptCore/wtf/ThreadingPthreads.cpp \
        JavaScriptCore/wtf/ThreadingPthreads.cpp \
+       JavaScriptCore/wtf/ThreadSafeShared.h \
        JavaScriptCore/wtf/ThreadSpecific.h \
        JavaScriptCore/wtf/TypeTraits.cpp \
        JavaScriptCore/wtf/TypeTraits.h \
        JavaScriptCore/wtf/UnusedParam.h \
        JavaScriptCore/wtf/ThreadSpecific.h \
        JavaScriptCore/wtf/TypeTraits.cpp \
        JavaScriptCore/wtf/TypeTraits.h \
        JavaScriptCore/wtf/UnusedParam.h \
+       JavaScriptCore/wtf/ValueCheck.h \
        JavaScriptCore/wtf/Vector.h \
        JavaScriptCore/wtf/VectorTraits.h \
        JavaScriptCore/wtf/Vector.h \
        JavaScriptCore/wtf/VectorTraits.h \
-       JavaScriptCore/wtf/gtk/GOwnPtr.cpp \
-       JavaScriptCore/wtf/gtk/GOwnPtr.h \
-       JavaScriptCore/wtf/gtk/GRefPtr.cpp \
-       JavaScriptCore/wtf/gtk/GRefPtr.h \
+       JavaScriptCore/wtf/WTFThreadData.cpp \
+       JavaScriptCore/wtf/WTFThreadData.h \
+       JavaScriptCore/wtf/gobject/GOwnPtr.cpp \
+       JavaScriptCore/wtf/gobject/GOwnPtr.h \
+       JavaScriptCore/wtf/gobject/GRefPtr.cpp \
+       JavaScriptCore/wtf/gobject/GRefPtr.h \
        JavaScriptCore/wtf/gtk/MainThreadGtk.cpp \
        JavaScriptCore/wtf/gtk/ThreadingGtk.cpp \
        JavaScriptCore/wtf/gtk/MainThreadGtk.cpp \
        JavaScriptCore/wtf/gtk/ThreadingGtk.cpp \
+       JavaScriptCore/wtf/text/AtomicString.cpp \
+       JavaScriptCore/wtf/text/AtomicString.h \
+       JavaScriptCore/wtf/text/AtomicStringImpl.h \
+       JavaScriptCore/wtf/text/CString.cpp \
+       JavaScriptCore/wtf/text/CString.h \
+       JavaScriptCore/wtf/text/StringHash.h \
+       JavaScriptCore/wtf/text/StringImpl.cpp \
+       JavaScriptCore/wtf/text/StringImpl.h \
+       JavaScriptCore/wtf/text/StringStatics.cpp \
+       JavaScriptCore/wtf/text/WTFString.cpp \
+       JavaScriptCore/wtf/text/WTFString.h \
        JavaScriptCore/wtf/unicode/Collator.h \
        JavaScriptCore/wtf/unicode/CollatorDefault.cpp \
        JavaScriptCore/wtf/unicode/UTF8.cpp \
        JavaScriptCore/wtf/unicode/Collator.h \
        JavaScriptCore/wtf/unicode/CollatorDefault.cpp \
        JavaScriptCore/wtf/unicode/UTF8.cpp \
@@ -484,13 +507,18 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/PutPropertySlot.h \
        JavaScriptCore/runtime/RegExp.cpp \
        JavaScriptCore/runtime/RegExp.h \
        JavaScriptCore/runtime/PutPropertySlot.h \
        JavaScriptCore/runtime/RegExp.cpp \
        JavaScriptCore/runtime/RegExp.h \
+       JavaScriptCore/runtime/RegExpCache.cpp \
+       JavaScriptCore/runtime/RegExpCache.h \
        JavaScriptCore/runtime/RegExpConstructor.cpp \
        JavaScriptCore/runtime/RegExpConstructor.h \
        JavaScriptCore/runtime/RegExpConstructor.cpp \
        JavaScriptCore/runtime/RegExpConstructor.h \
+       JavaScriptCore/runtime/RegExpKey.h \
        JavaScriptCore/runtime/RegExpMatchesArray.h \
        JavaScriptCore/runtime/RegExpObject.cpp \
        JavaScriptCore/runtime/RegExpObject.h \
        JavaScriptCore/runtime/RegExpPrototype.cpp \
        JavaScriptCore/runtime/RegExpPrototype.h \
        JavaScriptCore/runtime/RegExpMatchesArray.h \
        JavaScriptCore/runtime/RegExpObject.cpp \
        JavaScriptCore/runtime/RegExpObject.h \
        JavaScriptCore/runtime/RegExpPrototype.cpp \
        JavaScriptCore/runtime/RegExpPrototype.h \
+       JavaScriptCore/runtime/RopeImpl.cpp \
+       JavaScriptCore/runtime/RopeImpl.h \
        JavaScriptCore/runtime/ScopeChain.cpp \
        JavaScriptCore/runtime/ScopeChain.h \
        JavaScriptCore/runtime/ScopeChainMark.h \
        JavaScriptCore/runtime/ScopeChain.cpp \
        JavaScriptCore/runtime/ScopeChain.h \
        JavaScriptCore/runtime/ScopeChainMark.h \
@@ -505,7 +533,6 @@ javascriptcore_sources += \
        JavaScriptCore/runtime/Tracing.h \
        JavaScriptCore/runtime/UString.cpp \
        JavaScriptCore/runtime/UString.h \
        JavaScriptCore/runtime/Tracing.h \
        JavaScriptCore/runtime/UString.cpp \
        JavaScriptCore/runtime/UString.h \
-       JavaScriptCore/runtime/UStringImpl.cpp \
        JavaScriptCore/runtime/UStringImpl.h \
        JavaScriptCore/runtime/WeakRandom.h \
        JavaScriptCore/wtf/FastAllocBase.h \
        JavaScriptCore/runtime/UStringImpl.h \
        JavaScriptCore/runtime/WeakRandom.h \
        JavaScriptCore/wtf/FastAllocBase.h \
@@ -535,6 +562,9 @@ DerivedSources/Lexer.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/parser
 JavaScriptCore/%.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/%.cpp
        $(PERL) $^ -i > $@
 
 JavaScriptCore/%.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/%.cpp
        $(PERL) $^ -i > $@
 
+JavaScriptCore/RegExpJitTables.h: $(srcdir)/JavaScriptCore/create_regex_tables
+       $(PYTHON) $(srcdir)/JavaScriptCore/create_regex_tables > $@
+
 JavaScriptCore/pcre/chartables.c: $(srcdir)/JavaScriptCore/pcre/dftables
        $(PERL) $^ $@
 
 JavaScriptCore/pcre/chartables.c: $(srcdir)/JavaScriptCore/pcre/dftables
        $(PERL) $^ $@
 
@@ -595,6 +625,7 @@ Programs_jsc_LDADD = \
 
 javascriptcore_dist += \
        $(CREATE_HASH_TABLE) \
 
 javascriptcore_dist += \
        $(CREATE_HASH_TABLE) \
+       $(CREATE_REGEXP_TABLES) \
        JavaScriptCore/AUTHORS \
        JavaScriptCore/COPYING.LIB \
        JavaScriptCore/ChangeLog \
        JavaScriptCore/AUTHORS \
        JavaScriptCore/COPYING.LIB \
        JavaScriptCore/ChangeLog \
index aa82120981d88bdb62e8d0f17cb0817f4fab82ee..3f408c6cbf261fd9e33eff54a115b8b0b4e5d25b 100644 (file)
@@ -1,3 +1,5 @@
+__ZN7WebCore10StringImpl6createEPKcj
+__ZN7WebCore12AtomicString11addSlowCaseEPNS_10StringImplE
 _JSCheckScriptSyntax
 _JSClassCreate
 _JSClassRelease
 _JSCheckScriptSyntax
 _JSClassCreate
 _JSClassRelease
@@ -18,8 +20,10 @@ _JSGlobalContextRetain
 _JSObjectCallAsConstructor
 _JSObjectCallAsFunction
 _JSObjectCopyPropertyNames
 _JSObjectCallAsConstructor
 _JSObjectCallAsFunction
 _JSObjectCopyPropertyNames
+_JSObjectDeletePrivateProperty
 _JSObjectDeleteProperty
 _JSObjectGetPrivate
 _JSObjectDeleteProperty
 _JSObjectGetPrivate
+_JSObjectGetPrivateProperty
 _JSObjectGetProperty
 _JSObjectGetPropertyAtIndex
 _JSObjectGetPrototype
 _JSObjectGetProperty
 _JSObjectGetPropertyAtIndex
 _JSObjectGetPrototype
@@ -35,6 +39,7 @@ _JSObjectMakeFunction
 _JSObjectMakeFunctionWithCallback
 _JSObjectMakeRegExp
 _JSObjectSetPrivate
 _JSObjectMakeFunctionWithCallback
 _JSObjectMakeRegExp
 _JSObjectSetPrivate
+_JSObjectSetPrivateProperty
 _JSObjectSetProperty
 _JSObjectSetPropertyAtIndex
 _JSObjectSetPrototype
 _JSObjectSetProperty
 _JSObjectSetPropertyAtIndex
 _JSObjectSetPrototype
@@ -57,6 +62,7 @@ _JSStringIsEqual
 _JSStringIsEqualToUTF8CString
 _JSStringRelease
 _JSStringRetain
 _JSStringIsEqualToUTF8CString
 _JSStringRelease
 _JSStringRetain
+_JSValueCreateJSONString
 _JSValueGetType
 _JSValueIsBoolean
 _JSValueIsEqual
 _JSValueGetType
 _JSValueIsBoolean
 _JSValueIsEqual
@@ -69,6 +75,7 @@ _JSValueIsStrictEqual
 _JSValueIsString
 _JSValueIsUndefined
 _JSValueMakeBoolean
 _JSValueIsString
 _JSValueIsUndefined
 _JSValueMakeBoolean
+_JSValueMakeFromJSONString
 _JSValueMakeNull
 _JSValueMakeNumber
 _JSValueMakeString
 _JSValueMakeNull
 _JSValueMakeNumber
 _JSValueMakeString
@@ -79,6 +86,10 @@ _JSValueToNumber
 _JSValueToObject
 _JSValueToStringCopy
 _JSValueUnprotect
 _JSValueToObject
 _JSValueToStringCopy
 _JSValueUnprotect
+_JSWeakObjectMapClear
+_JSWeakObjectMapCreate
+_JSWeakObjectMapGet
+_JSWeakObjectMapSet
 _WebCoreWebThreadIsLockedOrDisabled
 _WTFLog
 _WTFLogVerbose
 _WebCoreWebThreadIsLockedOrDisabled
 _WTFLog
 _WTFLogVerbose
@@ -91,12 +102,14 @@ __Z12jsRegExpFreeP8JSRegExp
 __Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
 __Z15jsRegExpExecutePK8JSRegExpPKtiiPii
 __ZN14OpaqueJSString6createERKN3JSC7UStringE
 __Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
 __Z15jsRegExpExecutePK8JSRegExpPKtiiPii
 __ZN14OpaqueJSString6createERKN3JSC7UStringE
-__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_11UStringImplE
-__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPNS_11UStringImplE
-__ZN3JSC10Identifier24checkSameIdentifierTableEPNS_12JSGlobalDataEPNS_11UStringImplE
-__ZN3JSC10Identifier24checkSameIdentifierTableEPNS_9ExecStateEPNS_11UStringImplE
+__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPN7WebCore10StringImplE
+__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPN7WebCore10StringImplE
+__ZN3JSC10Identifier27checkCurrentIdentifierTableEPNS_12JSGlobalDataE
+__ZN3JSC10Identifier27checkCurrentIdentifierTableEPNS_9ExecStateE
 __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
 __ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
-__ZN3JSC10Identifier5equalEPKNS_11UStringImplEPKc
+__ZN3JSC10Identifier4fromEPNS_9ExecStateEi
+__ZN3JSC10Identifier4fromEPNS_9ExecStateEj
+__ZN3JSC10Identifier5equalEPKN7WebCore10StringImplEPKc
 __ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
 __ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
 __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
@@ -104,24 +117,20 @@ __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringE
 __ZN3JSC11JSByteArray15createStructureENS_7JSValueE
 __ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
 __ZN3JSC11ParserArena5resetEv
 __ZN3JSC11JSByteArray15createStructureENS_7JSValueE
 __ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
 __ZN3JSC11ParserArena5resetEv
-__ZN3JSC11UStringImpl12sharedBufferEv
-__ZN3JSC11UStringImpl6s_nullE
-__ZN3JSC11UStringImpl7s_emptyE
-__ZN3JSC11UStringImplD1Ev
 __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
 __ZN3JSC12DateInstance4infoE
 __ZN3JSC12DateInstanceC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEd
 __ZN3JSC12DateInstanceC1EPNS_9ExecStateEd
 __ZN3JSC12JSGlobalData10ClientDataD2Ev
 __ZN3JSC12JSGlobalData11jsArrayVPtrE
 __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
 __ZN3JSC12DateInstance4infoE
 __ZN3JSC12DateInstanceC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEd
 __ZN3JSC12DateInstanceC1EPNS_9ExecStateEd
 __ZN3JSC12JSGlobalData10ClientDataD2Ev
 __ZN3JSC12JSGlobalData11jsArrayVPtrE
-__ZN3JSC12JSGlobalData12createLeakedEv
+__ZN3JSC12JSGlobalData12createLeakedENS_15ThreadStackTypeE
 __ZN3JSC12JSGlobalData12jsStringVPtrE
 __ZN3JSC12JSGlobalData12stopSamplingEv
 __ZN3JSC12JSGlobalData13startSamplingEv
 __ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE
 __ZN3JSC12JSGlobalData14resetDateCacheEv
 __ZN3JSC12JSGlobalData14sharedInstanceEv
 __ZN3JSC12JSGlobalData12jsStringVPtrE
 __ZN3JSC12JSGlobalData12stopSamplingEv
 __ZN3JSC12JSGlobalData13startSamplingEv
 __ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE
 __ZN3JSC12JSGlobalData14resetDateCacheEv
 __ZN3JSC12JSGlobalData14sharedInstanceEv
-__ZN3JSC12JSGlobalData6createEv
+__ZN3JSC12JSGlobalData6createENS_15ThreadStackTypeE
 __ZN3JSC12JSGlobalDataD1Ev
 __ZN3JSC12SamplingTool5setupEv
 __ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
 __ZN3JSC12JSGlobalDataD1Ev
 __ZN3JSC12SamplingTool5setupEv
 __ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
@@ -165,7 +174,7 @@ __ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescr
 __ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC16toUInt32SlowCaseEdRb
 __ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb
 __ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZN3JSC16toUInt32SlowCaseEdRb
 __ZN3JSC17BytecodeGenerator21setDumpsGeneratedCodeEb
-__ZN3JSC17PropertyNameArray3addEPNS_11UStringImplE
+__ZN3JSC17PropertyNameArray3addEPN7WebCore10StringImplE
 __ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
 __ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectES6_RKNS_7ArgListEE
 __ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
 __ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
 __ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectES6_RKNS_7ArgListEE
 __ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
@@ -186,12 +195,11 @@ __ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_
 __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
 __ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
 __ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
 __ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
-__ZN3JSC25g_identifierTableSpecificE
-__ZN3JSC29createIdentifierTableSpecificEv
 __ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
 __ZN3JSC3NaNE
 __ZN3JSC4Heap14primaryHeapEndEv
 __ZN3JSC4Heap15recordExtraCostEm
 __ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
 __ZN3JSC3NaNE
 __ZN3JSC4Heap14primaryHeapEndEv
 __ZN3JSC4Heap15recordExtraCostEm
+__ZN3JSC4Heap16objectTypeCountsEv
 __ZN3JSC4Heap16primaryHeapBeginEv
 __ZN3JSC4Heap17collectAllGarbageEv
 __ZN3JSC4Heap17globalObjectCountEv
 __ZN3JSC4Heap16primaryHeapBeginEv
 __ZN3JSC4Heap17collectAllGarbageEv
 __ZN3JSC4Heap17globalObjectCountEv
@@ -204,12 +212,10 @@ __ZN3JSC4Heap7protectENS_7JSValueE
 __ZN3JSC4Heap8allocateEm
 __ZN3JSC4Heap9unprotectENS_7JSValueE
 __ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
 __ZN3JSC4Heap8allocateEm
 __ZN3JSC4Heap9unprotectENS_7JSValueE
 __ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
-__ZN3JSC5equalEPKNS_11UStringImplES2_
 __ZN3JSC6JSCell11getCallDataERNS_8CallDataE
 __ZN3JSC6JSCell11getJSNumberEv
 __ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateEj
 __ZN3JSC6JSCell11getCallDataERNS_8CallDataE
 __ZN3JSC6JSCell11getJSNumberEv
 __ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateEj
-__ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
 __ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
 __ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
 __ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
@@ -225,12 +231,14 @@ __ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE
 __ZN3JSC6JSLock9lockCountEv
 __ZN3JSC6JSLockC1EPNS_9ExecStateE
 __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
 __ZN3JSC6JSLock9lockCountEv
 __ZN3JSC6JSLockC1EPNS_9ExecStateE
 __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
-__ZN3JSC7CStringD1Ev
-__ZN3JSC7CStringaSERKS0_
+__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
+__ZN3JSC7JSArray15setSubclassDataEPv
 __ZN3JSC7JSArray4infoE
 __ZN3JSC7JSArray9setLengthEj
 __ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
 __ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7ArgListE
 __ZN3JSC7JSArray4infoE
 __ZN3JSC7JSArray9setLengthEj
 __ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
 __ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7ArgListE
+__ZN3JSC7JSArrayC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC7JSArrayD2Ev
 __ZN3JSC7Profile10restoreAllEv
 __ZN3JSC7Profile5focusEPKNS_11ProfileNodeE
 __ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE
 __ZN3JSC7Profile10restoreAllEv
 __ZN3JSC7Profile5focusEPKNS_11ProfileNodeE
 __ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE
@@ -240,8 +248,7 @@ __ZN3JSC7UString4fromEi
 __ZN3JSC7UString4fromEj
 __ZN3JSC7UString4fromEl
 __ZN3JSC7UStringC1EPKc
 __ZN3JSC7UString4fromEj
 __ZN3JSC7UString4fromEl
 __ZN3JSC7UStringC1EPKc
-__ZN3JSC7UStringC1EPKti
-__ZN3JSC7UStringaSEPKc
+__ZN3JSC7UStringC1EPKtj
 __ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE
 __ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
 __ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
 __ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE
 __ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
 __ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
@@ -271,7 +278,6 @@ __ZN3JSC8JSObject23allocatePropertyStorageEmm
 __ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE  
 __ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE  
-__ZN3JSC8JSString4RopeD1Ev
 __ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC8Profiler8profilerEv
 __ZN3JSC8Profiler13stopProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC8Profiler14startProfilingEPNS_9ExecStateERKNS_7UStringE
 __ZN3JSC8Profiler8profilerEv
@@ -282,7 +288,7 @@ __ZN3JSC9MarkStack10s_pageSizeE
 __ZN3JSC9MarkStack12releaseStackEPvm
 __ZN3JSC9MarkStack13allocateStackEm
 __ZN3JSC9MarkStack18initializePagesizeEv
 __ZN3JSC9MarkStack12releaseStackEPvm
 __ZN3JSC9MarkStack13allocateStackEm
 __ZN3JSC9MarkStack18initializePagesizeEv
-__ZN3JSC9Structure13hasTransitionEPNS_11UStringImplEj
+__ZN3JSC9Structure13hasTransitionEPN7WebCore10StringImplEj
 __ZN3JSC9Structure17stopIgnoringLeaksEv
 __ZN3JSC9Structure18startIgnoringLeaksEv
 __ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
 __ZN3JSC9Structure17stopIgnoringLeaksEv
 __ZN3JSC9Structure18startIgnoringLeaksEv
 __ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
@@ -291,7 +297,7 @@ __ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE
 __ZN3JSC9Structure27despecifyDictionaryFunctionERKNS_10IdentifierE
 __ZN3JSC9Structure27despecifyFunctionTransitionEPS0_RKNS_10IdentifierE
 __ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEjPNS_6JSCellE
 __ZN3JSC9Structure27despecifyDictionaryFunctionERKNS_10IdentifierE
 __ZN3JSC9Structure27despecifyFunctionTransitionEPS0_RKNS_10IdentifierE
 __ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEjPNS_6JSCellE
-__ZN3JSC9Structure3getEPKNS_11UStringImplERjRPNS_6JSCellE
+__ZN3JSC9Structure3getEPKN7WebCore10StringImplERjRPNS_6JSCellE
 __ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
 __ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoEj
 __ZN3JSC9StructureD1Ev
 __ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
 __ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoEj
 __ZN3JSC9StructureD1Ev
@@ -301,6 +307,7 @@ __ZN3JSCgtERKNS_7UStringES2_
 __ZN3JSCltERKNS_7UStringES2_
 __ZN3WTF10fastCallocEmm
 __ZN3WTF10fastMallocEm
 __ZN3JSCltERKNS_7UStringES2_
 __ZN3WTF10fastCallocEmm
 __ZN3WTF10fastMallocEm
+__ZN3WTF10fastStrDupEPKc
 __ZN3WTF11currentTimeEv
 __ZN3WTF11fastReallocEPvm
 __ZN3WTF12createThreadEPFPvS0_ES0_
 __ZN3WTF11currentTimeEv
 __ZN3WTF11fastReallocEPvm
 __ZN3WTF12createThreadEPFPvS0_ES0_
@@ -308,9 +315,13 @@ __ZN3WTF12createThreadEPFPvS0_ES0_PKc
 __ZN3WTF12detachThreadEj
 __ZN3WTF12isMainThreadEv
 __ZN3WTF12randomNumberEv
 __ZN3WTF12detachThreadEj
 __ZN3WTF12isMainThreadEv
 __ZN3WTF12randomNumberEv
+__ZN3WTF13WTFThreadData10staticDataE
+__ZN3WTF13WTFThreadDataC1Ev
+__ZN3WTF13WTFThreadDataD1Ev
 __ZN3WTF13currentThreadEv
 __ZN3WTF13tryFastCallocEmm
 __ZN3WTF13tryFastMallocEm
 __ZN3WTF13currentThreadEv
 __ZN3WTF13tryFastCallocEmm
 __ZN3WTF13tryFastMallocEm
+__ZN3WTF14fastMallocSizeEPKv
 __ZN3WTF15ThreadCondition4waitERNS_5MutexE
 __ZN3WTF15ThreadCondition6signalEv
 __ZN3WTF15ThreadCondition9broadcastEv
 __ZN3WTF15ThreadCondition4waitERNS_5MutexE
 __ZN3WTF15ThreadCondition6signalEv
 __ZN3WTF15ThreadCondition9broadcastEv
@@ -323,6 +334,7 @@ __ZN3WTF18dateToDaysFrom1970Eiii
 __ZN3WTF18monthFromDayInYearEib
 __ZN3WTF19initializeThreadingEv
 __ZN3WTF20fastMallocStatisticsEv
 __ZN3WTF18monthFromDayInYearEib
 __ZN3WTF19initializeThreadingEv
 __ZN3WTF20fastMallocStatisticsEv
+__ZN3WTF20initializeMainThreadEv
 __ZN3WTF21RefCountedLeakCounter16suppressMessagesEPKc
 __ZN3WTF21RefCountedLeakCounter24cancelMessageSuppressionEPKc
 __ZN3WTF21RefCountedLeakCounter9decrementEv
 __ZN3WTF21RefCountedLeakCounter16suppressMessagesEPKc
 __ZN3WTF21RefCountedLeakCounter24cancelMessageSuppressionEPKc
 __ZN3WTF21RefCountedLeakCounter9decrementEv
@@ -338,24 +350,113 @@ __ZN3WTF32doubleToStringInJavaScriptFormatEdPcPj
 __ZN3WTF36lockAtomicallyInitializedStaticMutexEv
 __ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
 __ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
 __ZN3WTF36lockAtomicallyInitializedStaticMutexEv
 __ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
 __ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
+__ZN3WTF39initializeMainThreadToProcessMainThreadEv
+__ZN3WTF3MD58addBytesEPKhm
+__ZN3WTF3MD58checksumEv
+__ZN3WTF3MD5C1Ev
 __ZN3WTF5Mutex4lockEv
 __ZN3WTF5Mutex6unlockEv
 __ZN3WTF5Mutex7tryLockEv
 __ZN3WTF5MutexC1Ev
 __ZN3WTF5MutexD1Ev
 __ZN3WTF6strtodEPKcPPc
 __ZN3WTF5Mutex4lockEv
 __ZN3WTF5Mutex6unlockEv
 __ZN3WTF5Mutex7tryLockEv
 __ZN3WTF5MutexC1Ev
 __ZN3WTF5MutexD1Ev
 __ZN3WTF6strtodEPKcPPc
+__ZN3WTF7CString11mutableDataEv
+__ZN3WTF7CString16newUninitializedEmRPc
+__ZN3WTF7CStringC1EPKc
+__ZN3WTF7CStringC1EPKcj
 __ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
 __ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
+__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b
 __ZN3WTF8Collator18setOrderLowerFirstEb
 __ZN3WTF8CollatorC1EPKc
 __ZN3WTF8CollatorD1Ev
 __ZN3WTF8fastFreeEPv
 __ZN3WTF8msToYearEd
 __ZN3WTF8Collator18setOrderLowerFirstEb
 __ZN3WTF8CollatorC1EPKc
 __ZN3WTF8CollatorD1Ev
 __ZN3WTF8fastFreeEPv
 __ZN3WTF8msToYearEd
-__ZN3WTF9dayInYearEdi
 __ZN3WTF9ByteArray6createEm
 __ZN3WTF9ByteArray6createEm
+__ZN3WTF9dayInYearEdi
+__ZN3WTFeqERKNS_7CStringES2_
+__ZN7WebCore10StringImpl11reverseFindEPS0_ib
+__ZN7WebCore10StringImpl11reverseFindEti
+__ZN7WebCore10StringImpl12sharedBufferEv
+__ZN7WebCore10StringImpl18simplifyWhiteSpaceEv
+__ZN7WebCore10StringImpl19characterStartingAtEj
+__ZN7WebCore10StringImpl19createUninitializedEjRPt
+__ZN7WebCore10StringImpl22containsOnlyWhitespaceEv
+__ZN7WebCore10StringImpl23defaultWritingDirectionEv
+__ZN7WebCore10StringImpl37createStrippingNullCharactersSlowCaseEPKtj
+__ZN7WebCore10StringImpl4findEPFbtEi
+__ZN7WebCore10StringImpl4findEPKcib
+__ZN7WebCore10StringImpl4findEPS0_ib
+__ZN7WebCore10StringImpl4findEti
+__ZN7WebCore10StringImpl5adoptERNS_12StringBufferE
+__ZN7WebCore10StringImpl5emptyEv
+__ZN7WebCore10StringImpl5lowerEv
+__ZN7WebCore10StringImpl5toIntEPb
+__ZN7WebCore10StringImpl5upperEv
+__ZN7WebCore10StringImpl6createEPKc
+__ZN7WebCore10StringImpl6createEPKtj
+__ZN7WebCore10StringImpl6createEPKtjN3WTF10PassRefPtrINS3_21CrossThreadRefCountedINS3_16OwnFastMallocPtrIS1_EEEEEE
+__ZN7WebCore10StringImpl6secureEtb
+__ZN7WebCore10StringImpl7replaceEPS0_S1_
+__ZN7WebCore10StringImpl7replaceEjjPS0_
+__ZN7WebCore10StringImpl7replaceEtPS0_
+__ZN7WebCore10StringImpl7replaceEtt
+__ZN7WebCore10StringImpl8endsWithEPS0_b
+__ZN7WebCore10StringImpl9substringEjj
+__ZN7WebCore10StringImplD1Ev
+__ZN7WebCore11commentAtomE
+__ZN7WebCore12AtomicString3addEPKc
+__ZN7WebCore12AtomicString3addEPKt
+__ZN7WebCore12AtomicString3addEPKtj
+__ZN7WebCore12AtomicString3addEPKtjj
+__ZN7WebCore12AtomicString4findEPKtjj
+__ZN7WebCore12AtomicString4initEv
+__ZN7WebCore15charactersToIntEPKtmPb
+__ZN7WebCore17charactersToFloatEPKtmPb
+__ZN7WebCore17equalIgnoringCaseEPKtPKcj
+__ZN7WebCore17equalIgnoringCaseEPNS_10StringImplEPKc
+__ZN7WebCore17equalIgnoringCaseEPNS_10StringImplES1_
+__ZN7WebCore18charactersToDoubleEPKtmPb
+__ZN7WebCore20equalIgnoringNullityEPNS_10StringImplES1_
+__ZN7WebCore21charactersToIntStrictEPKtmPbi
+__ZN7WebCore22charactersToUIntStrictEPKtmPbi
+__ZN7WebCore5equalEPKNS_10StringImplEPKc
+__ZN7WebCore5equalEPKNS_10StringImplES2_
+__ZN7WebCore6String26fromUTF8WithLatin1FallbackEPKcm
+__ZN7WebCore6String29charactersWithNullTerminationEv
+__ZN7WebCore6String6appendEPKtj
+__ZN7WebCore6String6appendERKS0_
+__ZN7WebCore6String6appendEc
+__ZN7WebCore6String6appendEt
+__ZN7WebCore6String6formatEPKcz
+__ZN7WebCore6String6insertERKS0_j
+__ZN7WebCore6String6numberEd
+__ZN7WebCore6String6numberEi
+__ZN7WebCore6String6numberEj
+__ZN7WebCore6String6numberEl
+__ZN7WebCore6String6numberEm
+__ZN7WebCore6String6numberEt
+__ZN7WebCore6String6numberEx
+__ZN7WebCore6String6numberEy
+__ZN7WebCore6String6removeEji
+__ZN7WebCore6String8fromUTF8EPKc
+__ZN7WebCore6String8fromUTF8EPKcm
+__ZN7WebCore6String8truncateEj
+__ZN7WebCore6StringC1EPKt
+__ZN7WebCore7xmlAtomE
+__ZN7WebCore8nullAtomE
+__ZN7WebCore8starAtomE
+__ZN7WebCore8textAtomE
+__ZN7WebCore9emptyAtomE
+__ZN7WebCore9xmlnsAtomE
+__ZN7WebCoreeqERKNS_12AtomicStringEPKc
+__ZN7WebCoreplEPKcRKNS_6StringE
+__ZN7WebCoreplERKNS_6StringEPKc
+__ZN7WebCoreplERKNS_6StringES2_
 __ZNK3JSC10JSFunction23isHostFunctionNonInlineEv
 __ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
 __ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
 __ZNK3JSC10JSFunction23isHostFunctionNonInlineEv
 __ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
 __ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
-__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
+__ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE
+__ZNK3JSC14JSGlobalObject14isDynamicScopeERb
 __ZNK3JSC16InternalFunction9classInfoEv
 __ZNK3JSC16JSVariableObject16isVariableObjectEv
 __ZNK3JSC17DebuggerCallFrame10thisObjectEv
 __ZNK3JSC16InternalFunction9classInfoEv
 __ZNK3JSC16JSVariableObject16isVariableObjectEv
 __ZNK3JSC17DebuggerCallFrame10thisObjectEv
@@ -374,7 +475,6 @@ __ZNK3JSC4Heap10statisticsEv
 __ZNK3JSC4Heap11objectCountEv
 __ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
 __ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE
 __ZNK3JSC4Heap11objectCountEv
 __ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
 __ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE
-__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
 __ZNK3JSC6JSCell14isGetterSetterEv
 __ZNK3JSC6JSCell8toNumberEPNS_9ExecStateE
 __ZNK3JSC6JSCell8toObjectEPNS_9ExecStateE
 __ZNK3JSC6JSCell14isGetterSetterEv
 __ZNK3JSC6JSCell8toNumberEPNS_9ExecStateE
 __ZNK3JSC6JSCell8toObjectEPNS_9ExecStateE
@@ -385,6 +485,7 @@ __ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE
 __ZNK3JSC6JSCell9getUInt32ERj
 __ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE
 __ZNK3JSC7ArgList8getSliceEiRS0_
 __ZNK3JSC6JSCell9getUInt32ERj
 __ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE
 __ZNK3JSC7ArgList8getSliceEiRS0_
+__ZNK3JSC7JSArray12subclassDataEv
 __ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
 __ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
 __ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
 __ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
 __ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
 __ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
@@ -393,7 +494,7 @@ __ZNK3JSC7UString10UTF8StringEb
 __ZNK3JSC7UString14toStrictUInt32EPb
 __ZNK3JSC7UString5asciiEv
 __ZNK3JSC7UString6is8BitEv
 __ZNK3JSC7UString14toStrictUInt32EPb
 __ZNK3JSC7UString5asciiEv
 __ZNK3JSC7UString6is8BitEv
-__ZNK3JSC7UString6substrEii
+__ZNK3JSC7UString6substrEjj
 __ZNK3JSC7UString8toUInt32EPb
 __ZNK3JSC7UString8toUInt32EPbb
 __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
 __ZNK3JSC7UString8toUInt32EPb
 __ZNK3JSC7UString8toUInt32EPbb
 __ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
@@ -409,6 +510,32 @@ __ZNK3JSC8JSString11resolveRopeEPNS_9ExecStateE
 __ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
 __ZNK3JSC9HashTable11deleteTableEv
 __ZNK3WTF8Collator7collateEPKtmS2_m
 __ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
 __ZNK3JSC9HashTable11deleteTableEv
 __ZNK3WTF8Collator7collateEPKtmS2_m
+__ZNK7WebCore12AtomicString5lowerEv
+__ZNK7WebCore6String11toIntStrictEPbi
+__ZNK7WebCore6String12toUIntStrictEPbi
+__ZNK7WebCore6String14threadsafeCopyEv
+__ZNK7WebCore6String15stripWhiteSpaceEv
+__ZNK7WebCore6String16removeCharactersEPFbtE
+__ZNK7WebCore6String17crossThreadStringEv
+__ZNK7WebCore6String18simplifyWhiteSpaceEv
+__ZNK7WebCore6String19characterStartingAtEj
+__ZNK7WebCore6String4utf8Ev
+__ZNK7WebCore6String5asciiEv
+__ZNK7WebCore6String5lowerEv
+__ZNK7WebCore6String5splitERKS0_RN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5splitERKS0_bRN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5splitEtRN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5splitEtbRN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5toIntEPb
+__ZNK7WebCore6String5upperEv
+__ZNK7WebCore6String6latin1Ev
+__ZNK7WebCore6String6toUIntEPb
+__ZNK7WebCore6String7toFloatEPb
+__ZNK7WebCore6String8foldCaseEv
+__ZNK7WebCore6String8toDoubleEPb
+__ZNK7WebCore6String8toIntPtrEPb
+__ZNK7WebCore6String8toUInt64EPb
+__ZNK7WebCore6String9substringEjj
 __ZTVN3JSC12StringObjectE
 __ZTVN3JSC14JSGlobalObjectE
 __ZTVN3JSC15JSWrapperObjectE
 __ZTVN3JSC12StringObjectE
 __ZTVN3JSC14JSGlobalObjectE
 __ZTVN3JSC15JSWrapperObjectE
index 66f40e9587af63973a84c044521358a6f3504765..9e014ddbdc91fe40f8394fecd3209618c0bad2ae 100644 (file)
         # ... Then include what we want.
         ['include', '../wtf/'],
         # GLib/GTK, even though its name doesn't really indicate.
         # ... Then include what we want.
         ['include', '../wtf/'],
         # GLib/GTK, even though its name doesn't really indicate.
-        ['exclude', '/(gtk|glib)/.*\\.(cpp|h)$'],
+        ['exclude', '/(gtk|glib|gobject)/.*\\.(cpp|h)$'],
         ['exclude', '(Default|Gtk|Mac|None|Qt|Win|Wx)\\.(cpp|mm)$'],
         ['exclude', 'wtf/CurrentTime\\.cpp$'],
         ['exclude', '(Default|Gtk|Mac|None|Qt|Win|Wx)\\.(cpp|mm)$'],
         ['exclude', 'wtf/CurrentTime\\.cpp$'],
+        ['exclude', 'wtf/MainThread.cpp$'],
         ['exclude', 'wtf/TC.*\\.(cpp|h)$'],
       ],
       'direct_dependent_settings': {
         ['exclude', 'wtf/TC.*\\.(cpp|h)$'],
       ],
       'direct_dependent_settings': {
index 24577dabadf45568cae1a0f4cbb6a85313fce8ba..787e0e6813f7ac507cd3230b59b1b5d261c2b66a 100644 (file)
             'jit/JIT.cpp',
             'jit/JIT.h',
             'jit/JITArithmetic.cpp',
             'jit/JIT.cpp',
             'jit/JIT.h',
             'jit/JITArithmetic.cpp',
+            'jit/JITArithmetic32_64.cpp',
             'jit/JITCall.cpp',
             'jit/JITCode.h',
             'jit/JITInlineMethods.h',
             'jit/JITOpcodes.cpp',
             'jit/JITCall.cpp',
             'jit/JITCode.h',
             'jit/JITInlineMethods.h',
             'jit/JITOpcodes.cpp',
+            'jit/JITOpcodes32_64.cpp',
             'jit/JITPropertyAccess.cpp',
             'jit/JITPropertyAccess.cpp',
+            'jit/JITPropertyAccess32_64.cpp',
             'jit/JITStubCall.h',
             'jit/JITStubs.cpp',
             'jit/JITStubs.h',
             'jit/JITStubCall.h',
             'jit/JITStubs.cpp',
             'jit/JITStubs.h',
             'runtime/PutPropertySlot.h',
             'runtime/RegExp.cpp',
             'runtime/RegExp.h',
             'runtime/PutPropertySlot.h',
             'runtime/RegExp.cpp',
             'runtime/RegExp.h',
+            'runtime/RegExpCache.cpp',
+            'runtime/RegExpCache.h',
             'runtime/RegExpConstructor.cpp',
             'runtime/RegExpConstructor.h',
             'runtime/RegExpConstructor.cpp',
             'runtime/RegExpConstructor.h',
+            'runtime/RegExpKey.h',
             'runtime/RegExpMatchesArray.h',
             'runtime/RegExpObject.cpp',
             'runtime/RegExpObject.h',
             'runtime/RegExpMatchesArray.h',
             'runtime/RegExpObject.cpp',
             'runtime/RegExpObject.h',
             'runtime/StructureChain.h',
             'runtime/StructureTransitionTable.h',
             'runtime/SymbolTable.h',
             'runtime/StructureChain.h',
             'runtime/StructureTransitionTable.h',
             'runtime/SymbolTable.h',
+            'runtime/Terminator.h',
             'runtime/TimeoutChecker.cpp',
             'runtime/TimeoutChecker.h',
             'runtime/Tracing.h',
             'runtime/UString.cpp',
             'runtime/UString.h',
             'runtime/WeakRandom.h',
             'runtime/TimeoutChecker.cpp',
             'runtime/TimeoutChecker.h',
             'runtime/Tracing.h',
             'runtime/UString.cpp',
             'runtime/UString.h',
             'runtime/WeakRandom.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/AlwaysInline.h',
             'wtf/ASCIICType.h',
             'wtf/Assertions.cpp',
             'wtf/Assertions.h',
+            'wtf/Atomics.h',
             'wtf/AVLTree.h',
             'wtf/ByteArray.cpp',
             'wtf/ByteArray.h',
             'wtf/AVLTree.h',
             'wtf/ByteArray.cpp',
             'wtf/ByteArray.h',
             'wtf/FastMalloc.h',
             'wtf/Forward.h',
             'wtf/GetPtr.h',
             'wtf/FastMalloc.h',
             'wtf/Forward.h',
             'wtf/GetPtr.h',
-            'wtf/gtk/GOwnPtr.cpp',
-            'wtf/gtk/GOwnPtr.h',
+            'wtf/gobject/GOwnPtr.cpp',
+            'wtf/gobject/GOwnPtr.h',
             'wtf/gtk/MainThreadGtk.cpp',
             'wtf/gtk/ThreadingGtk.cpp',
             'wtf/HashCountedSet.h',
             'wtf/gtk/MainThreadGtk.cpp',
             'wtf/gtk/ThreadingGtk.cpp',
             'wtf/HashCountedSet.h',
             'wtf/ListHashSet.h',
             'wtf/ListRefPtr.h',
             'wtf/Locker.h',
             'wtf/ListHashSet.h',
             'wtf/ListRefPtr.h',
             'wtf/Locker.h',
+            'wtf/MD5.cpp',
+            'wtf/MD5.h',
             'wtf/MainThread.cpp',
             'wtf/MainThread.h',
             'wtf/MallocZoneSupport.h',
             'wtf/MainThread.cpp',
             'wtf/MainThread.h',
             'wtf/MallocZoneSupport.h',
             'wtf/OwnFastMallocPtr.h',
             'wtf/OwnPtr.h',
             'wtf/OwnPtrCommon.h',
             'wtf/OwnFastMallocPtr.h',
             'wtf/OwnPtr.h',
             'wtf/OwnPtrCommon.h',
-            'wtf/OwnPtrWin.cpp',
             'wtf/PassOwnPtr.h',
             'wtf/PassRefPtr.h',
             'wtf/Platform.h',
             'wtf/PassOwnPtr.h',
             'wtf/PassRefPtr.h',
             'wtf/Platform.h',
             'wtf/RefPtrHashMap.h',
             'wtf/RetainPtr.h',
             'wtf/SegmentedVector.h',
             'wtf/RefPtrHashMap.h',
             'wtf/RetainPtr.h',
             'wtf/SegmentedVector.h',
+            'wtf/StaticConstructors.h',
             'wtf/StdLibExtras.h',
             'wtf/StringExtras.h',
             'wtf/StringHashFunctions.h',
             'wtf/TCPackedCache.h',
             'wtf/qt/MainThreadQt.cpp',
             'wtf/StdLibExtras.h',
             'wtf/StringExtras.h',
             'wtf/StringHashFunctions.h',
             'wtf/TCPackedCache.h',
             'wtf/qt/MainThreadQt.cpp',
+            'wtf/qt/StringQt.cpp',
             'wtf/qt/ThreadingQt.cpp',
             'wtf/TCPageMap.h',
             'wtf/TCSpinLock.h',
             'wtf/qt/ThreadingQt.cpp',
             'wtf/TCPageMap.h',
             'wtf/TCSpinLock.h',
             'wtf/Threading.cpp',
             'wtf/Threading.h',
             'wtf/ThreadingNone.cpp',
             'wtf/Threading.cpp',
             'wtf/Threading.h',
             'wtf/ThreadingNone.cpp',
+            'wtf/ThreadingPrimitives.h',
             'wtf/ThreadingPthreads.cpp',
             'wtf/ThreadingWin.cpp',
             'wtf/ThreadingPthreads.cpp',
             'wtf/ThreadingWin.cpp',
+            'wtf/ThreadSafeShared.h',
             'wtf/ThreadSpecific.h',
             'wtf/ThreadSpecificWin.cpp',
             'wtf/TypeTraits.cpp',
             'wtf/TypeTraits.h',
             'wtf/ThreadSpecific.h',
             'wtf/ThreadSpecificWin.cpp',
             'wtf/TypeTraits.cpp',
             'wtf/TypeTraits.h',
+            'wtf/text/AtomicString.cpp',
+            'wtf/text/AtomicString.h',
+            'wtf/text/AtomicStringImpl.h',
+            'wtf/text/CString.cpp',
+            'wtf/text/CString.h',
+            'wtf/text/StringHash.h',
+            'wtf/text/StringImpl.cpp',
+            'wtf/text/StringImpl.h',
+            'wtf/text/StringStatics.cpp',
+            'wtf/text/WTFString.cpp',
+            'wtf/text/WTFString.h',
             'wtf/unicode/Collator.h',
             'wtf/unicode/CollatorDefault.cpp',
             'wtf/unicode/glib/UnicodeGLib.cpp',
             'wtf/unicode/Collator.h',
             'wtf/unicode/CollatorDefault.cpp',
             'wtf/unicode/glib/UnicodeGLib.cpp',
             'wtf/unicode/UTF8.cpp',
             'wtf/unicode/UTF8.h',
             'wtf/UnusedParam.h',
             'wtf/unicode/UTF8.cpp',
             'wtf/unicode/UTF8.h',
             'wtf/UnusedParam.h',
+            'wtf/ValueCheck.h',
             'wtf/Vector.h',
             'wtf/VectorTraits.h',
             'wtf/VMTags.h',
             'wtf/Vector.h',
             'wtf/VectorTraits.h',
             'wtf/VMTags.h',
+            'wtf/WTFThreadData.cpp',
+            'wtf/WTFThreadData.h',
             'wtf/win/MainThreadWin.cpp',
             'wtf/win/MainThreadWin.cpp',
+            'wtf/win/OwnPtrWin.cpp',
             'wtf/wx/MainThreadWx.cpp',
             'yarr/RegexCompiler.cpp',
             'yarr/RegexCompiler.h',
             'wtf/wx/MainThreadWx.cpp',
             'yarr/RegexCompiler.cpp',
             'yarr/RegexCompiler.h',
diff --git a/JavaScriptCore.iPhone.order b/JavaScriptCore.iPhone.order
deleted file mode 100644 (file)
index aafa210..0000000
+++ /dev/null
@@ -1,1220 +0,0 @@
-__ZN3WTF10fastMallocEm
-__ZN3WTF10fastMallocILb1EEEPvm
-__ZN3WTF20TCMalloc_ThreadCache10InitModuleEv
- stub helpers
-__ZN3WTFL15InitSizeClassesEv
-__Z20TCMalloc_SystemAllocmPmm
-__ZN3WTF20TCMalloc_ThreadCache22CreateCacheIfNecessaryEv
-__ZN3WTF20TCMalloc_ThreadCache7NewHeapEP17_opaque_pthread_t
-__ZN3WTF20TCMalloc_ThreadCache14PickNextSampleEm
-__ZN3WTF25TCMalloc_Central_FreeList11RemoveRangeEPPvS2_Pi
-__ZN3WTF25TCMalloc_Central_FreeList18FetchFromSpansSafeEv
-__ZN3WTF17TCMalloc_PageHeap3NewEm
-__ZN3WTF17TCMalloc_PageHeap10AllocLargeEm
-__ZN3WTF17TCMalloc_PageHeap8GrowHeapEm
-__ZN3WTFL13MetaDataAllocEm
-__ZN3WTF17TCMalloc_PageHeap6DeleteEPNS_4SpanE
-__ZN3WTF17TCMalloc_PageHeap19IncrementalScavengeEm
-__Z22TCMalloc_SystemReleasePvm
-__ZN3WTF17TCMalloc_PageHeap5CarveEPNS_4SpanEmb
-__ZN3WTF16fastZeroedMallocEm
-__ZN3WTF8fastFreeEPv
-__ZN3WTF12isMainThreadEv
-__ZN3JSC19initializeThreadingEv
-__ZN3JSCL23initializeThreadingOnceEv
-__ZN3WTF19initializeThreadingEv
-__ZN3WTF20initializeMainThreadEv
-__ZN3WTF5MutexC1Ev
-__ZN3WTF28initializeMainThreadPlatformEv
-__ZN3JSC17initializeUStringEv
-__ZN3JSC12JSGlobalData10storeVPtrsEv
-__ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoEj
-__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC7JSArrayD1Ev
-__ZN3JSC7JSArrayD2Ev
-__ZN3JSC9StructureD1Ev
-__ZN3JSC9StructureD2Ev
-__ZN3JSC11JSByteArray15createStructureENS_7JSValueE
-__ZN3JSC11JSByteArrayD1Ev
-__ZN3JSC8JSStringD1Ev
-__ZN3JSC8JSStringD2Ev
-__ZN3JSC10JSFunctionC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC10JSFunctionD1Ev
-__ZN3JSC10JSFunctionD2Ev
-__ZN3JSC18VPtrHackExecutableD0Ev
-__ZN3JSC16InternalFunctionD2Ev
-__ZN3WTF15initializeDatesEv
-__ZN3WTF20equivalentYearForDSTEi
-__ZN3WTF11currentTimeEv
-__ZN3WTF14FastMallocZone4sizeEP14_malloc_zone_tPKv
-__ZN3WTF36lockAtomicallyInitializedStaticMutexEv
-__ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
-__ZN3WTF5Mutex4lockEv
-__ZN3WTF5Mutex6unlockEv
-__ZN3WTF6strtodEPKcPPc
-__ZN3JSC6JSLock12DropAllLocksC1ENS_14JSLockBehaviorE
-__ZN3JSC6JSLock12DropAllLocksC2ENS_14JSLockBehaviorE
-__ZN3JSCL17createJSLockCountEv
-__ZN3JSC6JSLock12DropAllLocksD1Ev
-__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv
-__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_
-__ZN3WTF20TCMalloc_ThreadCache21ReleaseToCentralCacheEmi
-__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv
-__ZN3WTF25TCMalloc_Central_FreeList14MakeCacheSpaceEv
-__ZN3WTF16callOnMainThreadEPFvPvES0_
-__ZN3WTF5DequeINS_19FunctionWithContextEE14expandCapacityEv
-__ZN3WTF37scheduleDispatchFunctionsOnMainThreadEv
--[WTFMainThreadCaller call]
-__ZN3WTF31dispatchFunctionsFromMainThreadEv
-__ZN3WTF15ThreadConditionC1Ev
-__ZN3WTF12createThreadEPFPvS0_ES0_PKc
-__ZN3WTF20createThreadInternalEPFPvS0_ES0_PKc
-__ZN3WTFL35establishIdentifierForPthreadHandleERKP17_opaque_pthread_t
-__ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_E6rehashEi
-__ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_E4findIjNS_22IdentityHashTranslatorIjS4_S8_EEEENS_17HashTableIteratorIjS4_S6_S8_SD_SB_EERKT_
-__ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEENSA_IS3_EEEESB_E3addIjS3_NS_17HashMapTranslatorIS4_SD_S8_EEEES1_INS_17HashTableIteratorIjS4_S6_S8_SD_SB_EEbERKT_RKT0_
-__ZN3WTF15ThreadCondition4waitERNS_5MutexE
-__ZN3WTFL16threadEntryPointEPv
-__ZN3WTF31initializeCurrentThreadInternalEPKc
-__ZN3WTF20ThreadIdentifierData10initializeEj
-__ZN3WTF20ThreadIdentifierData23initializeKeyOnceHelperEv
-__ZN3WTF5MutexD1Ev
-__ZN3WTF13currentThreadEv
-__ZN3WTF20ThreadIdentifierData10identifierEv
-__ZN3WTF15ThreadCondition9broadcastEv
-__ZN3WTF15ThreadCondition6signalEv
-__ZN3JSC12JSGlobalData12createLeakedEv
-__ZN3JSC9Structure18startIgnoringLeaksEv
-__ZN3JSC12JSGlobalDataC2Eb
-__ZN3JSC21createIdentifierTableEv
-__ZN3JSC17CommonIdentifiersC1EPNS_12JSGlobalDataE
-__ZN3JSC17CommonIdentifiersC2EPNS_12JSGlobalDataE
-__ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKc
-__ZNK3JSC11UStringImpl4hashEv
-__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC11UStringImplEEEENS_18PairFirstExtractorIS8_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSE_IS7_EEEESF_E4findIS2_NS_22IdentityHashTranslatorIS2_S8_SC_EEEENS_17HashTableIteratorIS2_S8_SA_SC_SH_SF_EERKT_
-__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC11UStringImplEEEENS_18PairFirstExtractorIS8_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSE_IS7_EEEESF_E6rehashEi
-__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC11UStringImplEEEENS_18PairFirstExtractorIS8_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSE_IS7_EEEESF_E3addIS2_S7_NS_17HashMapTranslatorIS8_SH_SC_EEEES3_INS_17HashTableIteratorIS2_S8_SA_SC_SH_SF_EEbERKT_RKT0_
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7StrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3JSC5equalEPKNS_11UStringImplES2_
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7StrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
-__ZN3JSC12SmallStringsC1Ev
-__ZN3JSC5LexerC1EPNS_12JSGlobalDataE
-__ZN3JSC11ParserArenaC1Ev
-__ZN3JSC11InterpreterC1Ev
-__ZN3JSC11InterpreterC2Ev
-__ZN3JSC11Interpreter14privateExecuteENS0_13ExecutionFlagEPNS_12RegisterFileEPNS_9ExecStateEPNS_7JSValueE
-__ZN3WTF9HashTableIPKvSt4pairIS2_N3JSC8OpcodeIDEENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E4findIS2_NS_22IdentityHashTranslatorIS2_S6_SA_EEEENS_17HashTableIteratorIS2_S6_S8_SA_SF_SD_EERKT_
-__ZN3WTF9HashTableIPKvSt4pairIS2_N3JSC8OpcodeIDEENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E6rehashEi
-__ZN3WTF9HashTableIPKvSt4pairIS2_N3JSC8OpcodeIDEENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSC_IS5_EEEESD_E3addIS2_S5_NS_17HashMapTranslatorIS6_SF_SA_EEEES3_INS_17HashTableIteratorIS2_S6_S8_SA_SF_SD_EEbERKT_RKT0_
-__ZN3JSC14TimeoutCheckerC1Ev
-__ZN3JSC4HeapC1EPNS_12JSGlobalDataE
-__ZN3JSC4Heap13allocateBlockEv
-__ZN3WTF11fastReallocEPvm
-__ZN3WTF11fastReallocILb1EEEPvS1_m
-__ZN3JSC9MarkStack18initializePagesizeEv
-__ZN3JSC9MarkStack13allocateStackEm
-__ZN3JSC27startProfilerServerIfNeededEv
-+[ProfilerServer sharedProfileServer]
--[ProfilerServer init]
-__ZN3JSC25setDefaultIdentifierTableEPNS_15IdentifierTableE
-__ZN3JSC29createIdentifierTableSpecificEv
-__ZN3JSCL37createIdentifierTableSpecificCallbackEv
-__ZN3JSC25setCurrentIdentifierTableEPNS_15IdentifierTableE
-__ZN3JSC9Structure17stopIgnoringLeaksEv
-__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
-__ZL30calculateCompiledPatternLengthPKti24JSRegExpIgnoreCaseOptionR11CompileDataR9ErrorCode
-__ZL11checkEscapePPKtS0_P9ErrorCodeib
-__ZL13compileBranchiPiPPhPPKtS3_P9ErrorCodeS_S_R11CompileData
-__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
-__ZL5matchPKtPKhiR9MatchData
-__ZN3JSC7UStringC1EPKti
-__ZN3JSC7UStringC2EPKti
-__ZN3WTF13tryFastMallocEm
-__ZN3WTF10fastMallocILb0EEEPvm
-__ZN3JSC11UStringImpl12sharedBufferEv
-__ZN3JSC4Heap8allocateEm
-__ZN3JSC6JSCellD1Ev
-__ZN3JSC4Heap7protectENS_7JSValueE
-__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E6rehashEi
-__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E4findIS3_NS_22IdentityHashTranslatorIS3_S5_S9_EEEENS_17HashTableIteratorIS3_S5_S7_S9_SE_SC_EERKT_
-__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E3addIS3_jNS_17HashMapTranslatorIS5_SE_S9_EEEES4_INS_17HashTableIteratorIS3_S5_S7_S9_SE_SC_EEbERKT_RKT0_
-__ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraitsIS3_EENSB_IjEEEESC_E3addIS3_S5_NS_22IdentityHashTranslatorIS3_S5_S9_EEEES4_INS_17HashTableIteratorIS3_S5_S7_S9_SE_SC_EEbERKT_RKT0_
-__ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
-__ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
-__ZN3JSC14JSGlobalObject5resetENS_7JSValueE
-__ZN3JSC17FunctionPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC17FunctionPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_10IdentifierE
-__ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE
-__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
-__ZN3JSC7UStringC1EPKc
-__ZN3JSCL9createRepEPKc
-__ZN3JSC8JSObject17putDirectInternalERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotEPNS_6JSCellE
-__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
-__ZNK3JSC24StructureTransitionTable3getERKSt4pairIN3WTF6RefPtrINS_11UStringImplEEEjEPNS_6JSCellE
-__ZN3JSC9Structure3getEPKNS_11UStringImplERjRPNS_6JSCellE
-__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
-__ZN3JSC9Structure3putERKNS_10IdentifierEjPNS_6JSCellE
-__ZN3JSC24StructureTransitionTable3addERKSt4pairIN3WTF6RefPtrINS_11UStringImplEEEjEPNS_9StructureEPNS_6JSCellE
-__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEjPNS_6JSCellE
-__ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_9StructureEPPNS_17PrototypeFunctionES7_
-__ZN3JSC17PrototypeFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
-__ZN3JSC17PrototypeFunctionC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
-__ZN3JSC8JSObject34putDirectFunctionWithoutTransitionEPNS_9ExecStateEPNS_16InternalFunctionEj
-__ZN3JSC16InternalFunction4nameEPNS_9ExecStateE
-__ZN3JSC9Structure3getERKNS_10IdentifierE
-__ZN3JSC15ObjectPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC15ObjectPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC9Structure26rehashPropertyMapHashTableEj
-__ZN3JSC8JSObject17createInheritorIDEv
-__ZN3JSC14ArrayPrototypeC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC7JSArrayC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC15StringPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC15StringPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC16BooleanPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC16BooleanPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC13BooleanObjectC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC15NumberPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC15NumberPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC12NumberObjectC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC13DatePrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC12DateInstanceC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC12nonInlineNaNEv
-__ZN3JSC15RegExpPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC15RegExpPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC14ErrorPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC14ErrorPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC13ErrorInstanceC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC18jsNontrivialStringEPNS_12JSGlobalDataEPKc
-__ZN3JSC20NativeErrorPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7UStringES9_
-__ZN3JSC17ObjectConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15ObjectPrototypeEPS5_
-__ZN3JSC17ObjectConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15ObjectPrototypeEPS5_
-__ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
-__ZN3JSC19FunctionConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_17FunctionPrototypeE
-__ZN3JSC19FunctionConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_17FunctionPrototypeE
-__ZNK3JSC16InternalFunction9classInfoEv
-__ZN3JSC16ArrayConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_14ArrayPrototypeEPS5_
-__ZN3JSC16ArrayConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_14ArrayPrototypeEPS5_
-__ZNK3JSC14ArrayPrototype9classInfoEv
-__ZN3JSC17StringConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_PNS_15StringPrototypeE
-__ZN3JSC17StringConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_PNS_15StringPrototypeE
-__ZNK3JSC15StringPrototype9classInfoEv
-__ZN3JSC18BooleanConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_16BooleanPrototypeE
-__ZN3JSC18BooleanConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_16BooleanPrototypeE
-__ZNK3JSC13BooleanObject9classInfoEv
-__ZN3JSC17NumberConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15NumberPrototypeE
-__ZN3JSC17NumberConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15NumberPrototypeE
-__ZN3JSC15DateConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_PNS_13DatePrototypeE
-__ZN3JSC15DateConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_PNS_13DatePrototypeE
-__ZNK3JSC13DatePrototype9classInfoEv
-__ZN3JSC17RegExpConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15RegExpPrototypeE
-__ZN3JSC17RegExpConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15RegExpPrototypeE
-__ZN3JSC16ErrorConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_14ErrorPrototypeE
-__ZN3JSC16ErrorConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_14ErrorPrototypeE
-__ZNK3JSC13ErrorInstance9classInfoEv
-__ZN3JSC22NativeErrorConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_20NativeErrorPrototypeE
-__ZN3JSC22NativeErrorConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_20NativeErrorPrototypeE
-__ZNK3JSC6JSCell9getStringEPNS_9ExecStateE
-__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPNS_11UStringImplE
-__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_11UStringImplE
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7StrHashIS3_EENS_10HashTraitsIS3_EES9_E3addIS3_S3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEESt4pairINS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EEbERKT_RKT0_
-__ZN3JSC8JSObject23allocatePropertyStorageEmm
-__ZN3JSC10MathObjectC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC10MathObjectC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC12SmallStrings24singleCharacterStringRepEh
-__ZN3JSC19SmallStringsStorageC2Ev
-__ZN3JSC14JSGlobalObject16addStaticGlobalsEPNS0_18GlobalPropertyInfoEi
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS4_EENS2_26SymbolTableIndexHashTraitsEEESD_E6rehashEi
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS4_EENS2_26SymbolTableIndexHashTraitsEEESD_E3addIPS3_S6_NS_29RefPtrHashMapRawKeyTranslatorISI_S7_SF_SA_EEEES5_INS_17HashTableIteratorIS4_S7_S9_SA_SF_SD_EEbERKT_RKT0_
-__ZN3JSC18GlobalEvalFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEEPNS_14JSGlobalObjectE
-__ZN3JSC14JSGlobalObject14resetPrototypeENS_7JSValueE
-__ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE
-__ZN3JSC9Structure17copyPropertyTableEv
-__ZN3JSC14JSGlobalObject10globalExecEv
-__ZN3JSC4Heap9unprotectENS_7JSValueE
-__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
-__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC14TimeoutChecker5resetEv
-__ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_7JSValueE
-__ZN3JSC6JSLockC1EPNS_9ExecStateE
-__ZN3JSC17ProgramExecutable7compileEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC6Parser5parseINS_11ProgramNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPiPNS_7UStringE
-__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
-__ZN3JSC7UStringaSEPKc
-__ZN3JSC5Lexer7setCodeERKNS_10SourceCodeERNS_11ParserArenaE
-__Z10jscyyparsePv
-__ZN3JSC5Lexer3lexEPvS1_
-__ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKti
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7StrHashIS3_EENS_10HashTraitsIS3_EES9_E18addPassingHashCodeINS1_11UCharBufferESC_NS_24HashSetTranslatorAdapterIS3_S9_SC_NS1_21UCharBufferTranslatorEEEEESt4pairINS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EEbERKT_RKT0_
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7StrHashIS3_EENS_10HashTraitsIS3_EES9_E18addPassingHashCodeIPKcSD_NS_24HashSetTranslatorAdapterIS3_S9_SD_NS1_17CStringTranslatorEEEEESt4pairINS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EEbERKT_RKT0_
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7StrHashIS3_EENS_10HashTraitsIS3_EES9_E20fullLookupForWritingINS1_11UCharBufferENS_24HashSetTranslatorAdapterIS3_S9_SC_NS1_21UCharBufferTranslatorEEEEESt4pairISG_IPS3_bEjERKT_
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7StrHashIS3_EENS_10HashTraitsIS3_EES9_E20fullLookupForWritingIPKcNS_24HashSetTranslatorAdapterIS3_S9_SD_NS1_17CStringTranslatorEEEEESt4pairISH_IPS3_bEjERKT_
-__ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EE6appendIS2_EEvRKT_
-__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataE
-__ZN3JSC11ParserArena14derefWithArenaEN3WTF10PassRefPtrINS_21ParserArenaRefCountedEEE
-__ZN3JSC5Lexer10sourceCodeEiii
-__ZN3JSC11ParserArena20allocateFreeablePoolEv
-__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeERKNS_10IdentifierE
-__ZN3JSC18FunctionParametersC2EPNS_13ParameterNodeE
-__ZN3WTF6VectorIPN3JSC20ParserArenaDeletableELm0EE14expandCapacityEmPKS3_
-__ZN3JSC13StatementNode6setLocEii
-__ZN3WTF6VectorIPN3JSC16FunctionBodyNodeELm0EE14expandCapacityEmPKS3_
-__ZN3JSC14SourceElements6appendEPNS_13StatementNodeE
-__ZNK3JSC13StatementNode16isEmptyStatementEv
-__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEmPKS3_
-__ZN3WTF6VectorIN3JSC10IdentifierELm0EE15reserveCapacityEm
-__Z21mergeDeclarationListsIPN3JSC15ParserArenaDataIN3WTF6VectorISt4pairIPKNS0_10IdentifierEjELm0EEEEEET_SC_SC_
-__Z21mergeDeclarationListsIPN3JSC15ParserArenaDataIN3WTF6VectorIPNS0_16FunctionBodyNodeELm0EEEEEET_S9_S9_
-__ZN3JSC5Lexer10scanRegExpERPKNS_10IdentifierES4_t
-__ZN3WTF6VectorItLm0EE14expandCapacityEmPKt
-__ZL20makeFunctionCallNodePN3JSC12JSGlobalDataENS_8NodeInfoIPNS_14ExpressionNodeEEENS2_IPNS_13ArgumentsNodeEEEiii
-__ZNK3JSC15DotAccessorNode10isLocationEv
-__ZNK3JSC14ExpressionNode13isResolveNodeEv
-__ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv
-__ZN3JSC5Lexer10skipRegExpEv
-__ZL14makeAssignNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeENS_8OperatorES3_bbiii
-__ZNK3JSC11ResolveNode10isLocationEv
-__ZNK3JSC11ResolveNode13isResolveNodeEv
-__ZN3WTF6VectorISt4pairIPKN3JSC10IdentifierEjELm0EE14expandCapacityEmPKS6_
-__ZNK3JSC14ExpressionNode10isLocationEv
-__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEmPKS4_
-__ZN3WTF6VectorIPvLm0EE14expandCapacityEmPKS1_
-__ZL11makeAddNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
-__ZNK3JSC14ExpressionNode8isNumberEv
-__ZN3JSC6Parser16didFinishParsingEPNS_14SourceElementsEPNS_15ParserArenaDataIN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEEEPNS3_INS5_IPNS_16FunctionBodyNodeELm0EEEEEjii
-__ZN3JSC5Lexer5clearEv
-__ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERKNS_10SourceCodeEji
-__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS9_IPNS_16FunctionBodyNodeELm0EEEji
-__ZN3JSC13ScopeNodeDataC2ERNS_11ParserArenaEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEEi
-__ZN3JSC11ParserArena10removeLastEv
-__ZN3JSC11ParserArena5resetEv
-__ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EE5clearEv
-__ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EE17deleteAllSegmentsEv
-__ZN3WTF6VectorIN3JSC10IdentifierELm64EE14shrinkCapacityEm
-__ZN3WTF6VectorINS_6RefPtrIN3JSC21ParserArenaRefCountedEEELm0EE14shrinkCapacityEm
-__ZN3JSC9CodeBlockC2EPNS_16ScriptExecutableENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourceProviderEEEjPNS4_7HashMapINS4_6RefPtrINS_11UStringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS4_10HashTraitsISB_EENS_26SymbolTableIndexHashTraitsEEE
-__ZN3WTF9HashTableIPN3JSC15GlobalCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E3addIS3_S3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEESt4pairINS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EEbERKT_RKT0_
-__ZN3WTF9HashTableIPN3JSC15GlobalCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3JSC17BytecodeGeneratorC1EPNS_11ProgramNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_11UStringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISD_EENS_26SymbolTableIndexHashTraitsEEEPNS_16ProgramCodeBlockE
-__ZN3JSC17BytecodeGeneratorC2EPNS_11ProgramNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_11UStringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISD_EENS_26SymbolTableIndexHashTraitsEEEPNS_16ProgramCodeBlockE
-__ZN3JSC17BytecodeGenerator10emitOpcodeENS_8OpcodeIDE
-__ZN3WTF15SegmentedVectorIN3JSC10RegisterIDELm32EE17ensureSegmentsForEm
-__ZN3WTF6VectorIN3JSC10RegisterIDELm32EE4growEm
-__ZN3JSC26BatchedTransitionOptimizerC2EPNS_8JSObjectE
-__ZN3JSC9Structure31toCacheableDictionaryTransitionEPS0_
-__ZN3JSC9Structure22toDictionaryTransitionEPS0_NS0_14DictionaryKindE
-__ZN3JSC24StructureTransitionTable6removeERKSt4pairIN3WTF6RefPtrINS_11UStringImplEEEjEPNS_6JSCellE
-__ZN3JSC8JSObject12removeDirectERKNS_10IdentifierE
-__ZN3JSC9Structure24removePropertyTransitionEPS0_RKNS_10IdentifierERm
-__ZN3JSC9Structure6removeERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE
-__ZN3WTF15SegmentedVectorIN3JSC10RegisterIDELm32EE6appendIiEEvRKT_
-__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_16FunctionBodyNodeE
-__ZN3JSC9CodeBlock15addFunctionDeclEN3WTF17NonNullPassRefPtrINS_18FunctionExecutableEEE
-__ZN3JSC9Structure31removePropertyWithoutTransitionERKNS_10IdentifierE
-__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZNK3JSC7UString14toStrictUInt32EPb
-__ZN3JSC17BytecodeGenerator16addConstantValueENS_7JSValueE
-__ZN3WTF6VectorIN3JSC8RegisterELm0EE14expandCapacityEmPKS2_
-__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_
-__ZN3JSC9Structure26flattenDictionaryStructureEPNS_8JSObjectE
-__ZN3JSCL30comparePropertyMapEntryIndicesEPKvS1_
-__ZN3JSC17BytecodeGenerator8generateEv
-__ZN3JSC11ProgramNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13emitDebugHookENS_11DebugHookIDEii
-__ZN3JSC17BytecodeGenerator12newTemporaryEv
-__ZN3WTF15SegmentedVectorIN3JSC10RegisterIDELm32EE6appendImEEvRKT_
-__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDENS_7JSValueE
-__ZN3JSC17BytecodeGenerator8emitNodeEPNS_10RegisterIDEPNS_4NodeE
-__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm
-__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8newLabelEv
-__ZN3WTF15SegmentedVectorIN3JSC5LabelELm32EE6appendIPNS1_9CodeBlockEEEvRKT_
-__ZNK3JSC13LogicalOpNode26hasConditionContextCodegenEv
-__ZN3JSC17BytecodeGenerator26emitNodeInConditionContextEPNS_14ExpressionNodeEPNS_5LabelES4_b
-__ZN3JSC13LogicalOpNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b
-__ZNK3JSC14ExpressionNode26hasConditionContextCodegenEv
-__ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC14ExpressionNode6isNullEv
-__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator18emitExpressionInfoEjjj
-__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEmPKS2_
-__ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3WTF6VectorIjLm0EE14expandCapacityEmPKj
-__ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_iENS_18PairFirstExtractorIS6_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS4_EENS2_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESC_E6rehashEi
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_iENS_18PairFirstExtractorIS6_EENS2_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS4_EENS2_17BytecodeGenerator28IdentifierMapIndexHashTraitsEEESC_E3addIPS3_iNS_29RefPtrHashMapRawKeyTranslatorISI_S6_SF_S9_EEEES5_INS_17HashTableIteratorIS4_S6_S8_S9_SF_SC_EEbERKT_RKT0_
-__ZN3JSC9CodeBlock13addIdentifierERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE
-__ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE
-__ZNK3JSC14LogicalNotNode26hasConditionContextCodegenEv
-__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC19FunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator15emitMethodCheckEv
-__ZN3JSC17BytecodeGenerator8emitCallEPNS_10RegisterIDES2_S2_PNS_13ArgumentsNodeEjjj
-__ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_S3_PNS_13ArgumentsNodeEjjj
-__ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
-__ZN3JSC6RegExpC2EPNS_12JSGlobalDataERKNS_7UStringES5_
-__ZNK3JSC7UString4findEti
-__ZN3JSC17BytecodeGenerator13emitNewRegExpEPNS_10RegisterIDEPNS_6RegExpE
-__ZN3JSC9CodeBlock9addRegExpEPNS_6RegExpE
-__ZN3JSC17BytecodeGenerator11emitUnaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_
-__ZN3JSC17BytecodeGenerator9emitLabelEPNS_5LabelE
-__ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRPNS_8JSObjectE
-__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
-__ZN3JSC9CodeBlock15addFunctionExprEN3WTF17NonNullPassRefPtrINS_18FunctionExecutableEEE
-__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_
-__ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator15emitResolveBaseEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator15isLocalConstantERKNS_10IdentifierE
-__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3WTF15SegmentedVectorIN3JSC5LabelELm32EE10removeLastEv
-__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE
-__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13emitNewObjectEPNS_10RegisterIDE
-__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3WTF9HashTableIPN3JSC11UStringImplESt4pairIS3_PNS1_8JSStringEENS_18PairFirstExtractorIS7_EENS1_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E6rehashEi
-__ZN3WTF9HashTableIPN3JSC11UStringImplESt4pairIS3_PNS1_8JSStringEENS_18PairFirstExtractorIS7_EENS1_17IdentifierRepHashENS_14PairHashTraitsINS_10HashTraitsIS3_EENSC_IS6_EEEESD_E3addIS3_S6_NS_17HashMapTranslatorIS7_SF_SA_EEEES4_INS_17HashTableIteratorIS3_S7_S9_SA_SF_SD_EEbERKT_RKT0_
-__ZN3JSC13jsOwnedStringEPNS_12JSGlobalDataERKNS_7UStringE
-__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZL14compileBracketiPiPPhPPKtS3_P9ErrorCodeiS_S_R11CompileData
-__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC11BooleanNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEb
-__ZL33bracketFindFirstAssertedCharacterPKhb
-__ZL32branchFindFirstAssertedCharacterPKhb
-__ZL20branchNeedsLineStartPKhjj
-__ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC17BytecodeGenerator7isLocalERKNS_10IdentifierE
-__ZN3JSC10NumberNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEd
-__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE
-__ZN3WTF9HashTableIxSt4pairIxjENS_18PairFirstExtractorIS2_EENS_7IntHashIxEENS_14PairHashTraitsIN3JSC24EncodedJSValueHashTraitsENS_10HashTraitsIjEEEES9_E4findIxNS_22IdentityHashTranslatorIxS2_S6_EEEENS_17HashTableIteratorIxS2_S4_S6_SC_S9_EERKT_
-__ZN3WTF9HashTableIxSt4pairIxjENS_18PairFirstExtractorIS2_EENS_7IntHashIxEENS_14PairHashTraitsIN3JSC24EncodedJSValueHashTraitsENS_10HashTraitsIjEEEES9_E6rehashEi
-__ZN3WTF9HashTableIxSt4pairIxjENS_18PairFirstExtractorIS2_EENS_7IntHashIxEENS_14PairHashTraitsIN3JSC24EncodedJSValueHashTraitsENS_10HashTraitsIjEEEES9_E3addIxjNS_17HashMapTranslatorIS2_SC_S6_EEEES1_INS_17HashTableIteratorIxS2_S4_S6_SC_S9_EEbERKT_RKT0_
-__ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE
-__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC14ExpressionNode5isAddEv
-__ZN3JSC21ThrowableBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC15StrictEqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_
-__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_PNS_13ArgumentsNodeEjjj
-__ZN3WTF6VectorIN3JSC20GetByIdExceptionInfoELm0EE14expandCapacityEmPKS2_
-__ZN3JSC17BytecodeGenerator16emitUnaryNoDstOpENS_8OpcodeIDEPNS_10RegisterIDE
-__ZN3JSC12JSGlobalData22numericCompareFunctionEPNS_9ExecStateE
-__ZNK3JSC21UStringSourceProvider6lengthEv
-__ZN3JSC18FunctionExecutable14fromGlobalCodeERKNS_10IdentifierEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
-__ZNK3JSC21UStringSourceProvider4dataEv
-__ZNK3JSC9ScopeNode15singleStatementEv
-__ZNK3JSC17ExprStatementNode15isExprStatementEv
-__ZNK3JSC12FuncExprNode14isFuncExprNodeEv
-__ZThn12_N3JSC11ProgramNodeD0Ev
-__ZN3JSC9ScopeNodeD2Ev
-__ZN3JSC11ParserArenaD1Ev
-__ZN3JSC14SourceElementsD1Ev
-__ZThn12_N3JSC16FunctionBodyNodeD0Ev
-__ZN3WTF10RefCountedIN3JSC18FunctionParametersEE5derefEv
-__ZN3WTF15SegmentedVectorIN3JSC10IdentifierELm64EED1Ev
-__ZN3JSC18FunctionExecutable7compileEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC6Parser5parseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPiPNS_7UStringE
-__ZL11makeSubNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
-__ZN3JSC14ExpressionNode14stripUnaryPlusEv
-__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPS0_Lm0EEERKNS_10SourceCodeEji
-__ZN3JSC16FunctionBodyNode13finishParsingEN3WTF10PassRefPtrINS_18FunctionParametersEEERKNS_10IdentifierE
-__ZN3JSC17BytecodeGeneratorC1EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_11UStringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISD_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE
-__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_11UStringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISD_EENS_26SymbolTableIndexHashTraitsEEEPNS_9CodeBlockE
-__ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierE
-__ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE
-__ZNK3JSC9BlockNode7isBlockEv
-__ZNK3JSC10ReturnNode12isReturnNodeEv
-__ZN3WTF6OwnPtrIN3JSC13ExceptionInfoEE5clearEv
-__ZN3JSC9CodeBlock11shrinkToFitEv
-__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorINS_6RefPtrIN3JSC18FunctionExecutableEEELm0EE14shrinkCapacityEm
-__ZN3JSC17BytecodeGeneratorD2Ev
-__ZN3WTF15SegmentedVectorIN3JSC10LabelScopeELm8EED1Ev
-__ZN3WTF15SegmentedVectorIN3JSC10LabelScopeELm8EE17deleteAllSegmentsEv
-__ZN3WTF15SegmentedVectorIN3JSC5LabelELm32EED1Ev
-__ZN3WTF15SegmentedVectorIN3JSC5LabelELm32EE17deleteAllSegmentsEv
-__ZN3WTF15SegmentedVectorIN3JSC10RegisterIDELm32EED1Ev
-__ZN3WTF6VectorIN3JSC11InstructionELm0EEaSERKS3_
-__ZN3JSC18FunctionExecutableD0Ev
-__ZN3JSC17FunctionCodeBlockD0Ev
-__ZN3JSC9CodeBlockD2Ev
-__ZN3WTF6OwnPtrIN3JSC13ExceptionInfoEED1Ev
-__ZN3JSC11UStringImplD1Ev
-__ZN3JSC11UStringImplD2Ev
-__ZN3JSC10Identifier6removeEPNS_11UStringImplE
-__ZN3JSC22currentIdentifierTableEv
-__ZN3JSC21UStringSourceProviderD0Ev
-__ZN3WTF6VectorINS_6RefPtrIN3JSC6RegExpEEELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm
-__ZN3JSC15ParserArenaDataIN3WTF6VectorIPNS_16FunctionBodyNodeELm0EEEED1Ev
-__ZN3JSC15ParserArenaDataIN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEED1Ev
-__ZN3WTF25TCMalloc_Central_FreeList11ShrinkCacheEib
-__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
-__ZN3JSC11Interpreter7executeEPNS_17ProgramExecutableEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectEPNS_7JSValueE
-__ZN3JSC12JSGlobalData14resetDateCacheEv
-__ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE
-__ZN3JSC18FunctionExecutable4makeEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_18FunctionExecutableEEEPNS_14ScopeChainNodeE
-__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
-__ZNK3JSC7JSValue3getEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC11Interpreter15tryCacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockEPNS_11InstructionENS_7JSValueERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC7JSValue13equalSlowCaseEPNS_9ExecStateES0_S0_
-__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC9Structure13hasTransitionEPNS_11UStringImplEj
-__ZN3JSC11Interpreter15tryCachePutByIDEPNS_9ExecStateEPNS_9CodeBlockEPNS_11InstructionENS_7JSValueERKNS_15PutPropertySlotE
-__ZN3JSC24StructureTransitionTable21reifySingleTransitionEv
-__ZN3WTF9HashTableISt4pairINS_6RefPtrIN3JSC11UStringImplEEEjES1_IS6_S1_IPNS3_9StructureES8_EENS_18PairFirstExtractorISA_EENS3_28StructureTransitionTableHashENS_14PairHashTraitsINS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEEESF_E4findIS6_NS_22IdentityHashTranslatorIS6_SA_SD_EEEENS_17HashTableIteratorIS6_SA_SC_SD_SI_SF_EERKT_
-__ZN3WTF9HashTableISt4pairINS_6RefPtrIN3JSC11UStringImplEEEjES1_IS6_S1_IPNS3_9StructureES8_EENS_18PairFirstExtractorISA_EENS3_28StructureTransitionTableHashENS_14PairHashTraitsINS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEEESF_E6rehashEi
-__ZN3WTF9HashTableISt4pairINS_6RefPtrIN3JSC11UStringImplEEEjES1_IS6_S1_IPNS3_9StructureES8_EENS_18PairFirstExtractorISA_EENS3_28StructureTransitionTableHashENS_14PairHashTraitsINS3_34StructureTransitionTableHashTraitsENS_10HashTraitsIS9_EEEESF_E3addIS6_S9_NS_17HashMapTranslatorISA_SI_SD_EEEES1_INS_17HashTableIteratorIS6_SA_SC_SD_SI_SF_EEbERKT_RKT0_
-__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE
-__ZL15makePostfixNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeENS_8OperatorEiii
-__ZNK3JSC10NumberNode8isNumberEv
-__ZN3JSC17BytecodeGenerator6addVarERKNS_10IdentifierEbRPNS_10RegisterIDE
-__ZNK3JSC16JSVariableObject16isVariableObjectEv
-__ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_7JSValueE
-__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE
-__ZN3WTF15SegmentedVectorIN3JSC10LabelScopeELm8EE6appendIS2_EEvRKT_
-__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
-__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi
-__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator10emitPreIncEPNS_10RegisterIDE
-__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_
-__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC17PrototypeFunction11getCallDataERNS_8CallDataE
-__ZNK3JSC7JSValue3getEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZNK3JSC12PropertySlot8getValueEPNS_9ExecStateEj
-__ZN3JSC7UString4fromEj
-__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
-__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE
-__ZN3JSC12RegExpObjectC1EN3WTF17NonNullPassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
-__ZN3JSC12RegExpObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC18getStaticValueSlotINS_12RegExpObjectENS_8JSObjectEEEbPNS_9ExecStateEPKNS_9HashTableEPT_RKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC12RegExpObject9classInfoEv
-__ZN3JSC12RegExpObject4testEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC12RegExpObject5matchEPNS_9ExecStateERKNS_7ArgListE
-__ZNK3JSC7JSValue8toStringEPNS_9ExecStateE
-__ZN3JSC17RegExpConstructor12performMatchEPNS_6RegExpERKNS_7UStringEiRiS6_PPi
-__ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF6VectorIiLm32EEE
-__ZN3JSC11Interpreter13resolveGlobalEPNS_9ExecStateEPNS_11InstructionERNS_7JSValueE
-__ZN3JSC17RegExpConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC18getStaticValueSlotINS_17RegExpConstructorENS_16InternalFunctionEEEbPNS_9ExecStateEPKNS_9HashTableEPT_RKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar1EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC11jsSubstringEPNS_12JSGlobalDataERKNS_7UStringEjj
-__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC8JSString12toThisStringEPNS_9ExecStateE
-__ZNK3JSC7UString4findERKS0_i
-__ZN3JSC7JSValue11strictEqualEPNS_9ExecStateES0_S0_
-__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEES4_NS_17IdentityExtractorIS4_EENS2_17IdentifierRepHashENS_10HashTraitsIS4_EES9_E6rehashEi
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEES4_NS_17IdentityExtractorIS4_EENS2_17IdentifierRepHashENS_10HashTraitsIS4_EES9_E3addIS4_S4_NS_22IdentityHashTranslatorIS4_S4_S7_EEEESt4pairINS_17HashTableIteratorIS4_S4_S6_S7_S9_S9_EEbERKT_RKT0_
-__ZNK3JSC13StatementNode12isReturnNodeEv
-__ZN3JSC12JSActivationC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_18FunctionExecutableEEE
-__ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
-__ZN3JSC12JSActivation13copyRegistersEPNS_9ArgumentsE
-__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC23CallFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator25emitJumpIfNotFunctionCallEPNS_10RegisterIDEPNS_5LabelE
-__ZN3JSC19ReverseBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
-__ZNK3JSC8JSObject9classNameEv
-__ZN3JSC10makeStringIPKcNS_7UStringES2_EES3_T_T0_T1_
-__ZN3JSC18jsNontrivialStringEPNS_12JSGlobalDataERKNS_7UStringE
-__ZN3JSC15TypeOfValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC20jsTypeStringForValueEPNS_9ExecStateENS_7JSValueE
-__ZN3JSC6JSCell11getCallDataERNS_8CallDataE
-__ZNK3JSC19BracketAccessorNode10isLocationEv
-__ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv
-__ZN3JSC9ForInNodeC2EPNS_12JSGlobalDataERKNS_10IdentifierEPNS_14ExpressionNodeES7_PNS_13StatementNodeEiii
-__ZN3JSC20ParserArenaDeletablenwEmPNS_12JSGlobalDataE
-__ZN3JSC9ForInNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator20emitGetPropertyNamesEPNS_10RegisterIDES2_S2_S2_PNS_5LabelE
-__ZN3JSC17BytecodeGenerator18pushOptimisedForInEPNS_10RegisterIDES2_S2_S2_
-__ZN3WTF6VectorIN3JSC12ForInContextELm0EE14expandCapacityEmPKS2_
-__ZN3WTF11VectorMoverILb0EN3JSC12ForInContextEE4moveEPKS2_S5_PS2_
-__ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_
-__ZN3JSC17BytecodeGenerator20emitNextPropertyNameEPNS_10RegisterIDES2_S2_S2_S2_PNS_5LabelE
-__ZN3JSC22JSPropertyNameIterator6createEPNS_9ExecStateEPNS_8JSObjectE
-__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
-__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
-__ZN3JSC9Structure16getPropertyNamesERNS_17PropertyNameArrayENS_15EnumerationModeE
-__ZN3JSC17PropertyNameArray14addKnownUniqueEPNS_11UStringImplE
-__ZNK3JSC6JSCell9classInfoEv
-__ZNK3JSC9Structure14prototypeChainEPNS_9ExecStateE
-__ZN3JSC14StructureChainC1EPNS_9StructureE
-__ZN3JSC14StructureChainC2EPNS_9StructureE
-__ZN3WTF10RefCountedIN3JSC21PropertyNameArrayDataEE5derefEv
-__ZN3JSC22JSPropertyNameIterator3getEPNS_9ExecStateEPNS_8JSObjectEm
-__ZN3JSC9Structure27despecifyFunctionTransitionEPS0_RKNS_10IdentifierE
-__ZN3JSC9Structure17despecifyFunctionERKNS_10IdentifierE
-__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC17RegExpConstructor3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC9lookupPutINS_17RegExpConstructorEEEbPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEPKNS_9HashTableEPT_
-__ZNK3JSC14ExpressionNode11isCommaNodeEv
-__ZN3JSC9CommaNodeC1EPNS_12JSGlobalDataEPNS_14ExpressionNodeES4_
-__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC12JSActivation14isDynamicScopeEv
-__ZN3JSC9CommaNodeD1Ev
-__ZN3JSC9ArgumentsC2EPNS_9ExecStateE
-__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11emitPostDecEPNS_10RegisterIDES2_
-__ZN3JSC17ObjectConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callObjectConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL19isInvalidParamForInEPNS_9ExecStateEPNS_9CodeBlockEPKNS_11InstructionENS_7JSValueERS7_
-__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC16ArrayConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL29constructWithArrayConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSCL27constructArrayWithSizeQuirkEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEEj
-__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC17TypeOfResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSCeqERKNS_7UStringEPKc
-__ZN3JSC16jsIsFunctionTypeENS_7JSValueE
-__ZN3JSC10JSFunction3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC9Structure22materializePropertyMapEv
-__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7ArgListE
-__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC7JSArray4pushEPNS_9ExecStateENS_7JSValueE
-__ZN3JSC7JSArray20increaseVectorLengthEj
-__ZN3WTF14tryFastReallocEPvm
-__ZN3WTF11fastReallocILb0EEEPvS1_m
-__ZNK3JSC9CodeBlock13refStructuresEPNS_11InstructionE
-__ZN3WTF6VectorIN3JSC10IdentifierELm20EE15reserveCapacityEm
-__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC11Interpreter14uncacheGetByIDEPNS_9CodeBlockEPNS_11InstructionE
-__ZNK3JSC9CodeBlock15derefStructuresEPNS_11InstructionE
-__ZNK3JSC9CommaNode11isCommaNodeEv
-__ZN3JSC9CommaNode6appendEPNS_14ExpressionNodeE
-__ZN3JSC7JSArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSCL20arrayProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC7JSArray9classInfoEv
-__ZNK3JSC9Arguments9classInfoEv
-__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_7JSValueE
-__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_7JSValueE
-__ZN3JSC7JSArray9setLengthEj
-__ZN3JSC17NumberConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC18getStaticValueSlotINS_17NumberConstructorENS_16InternalFunctionEEEbPNS_9ExecStateEPKNS_9HashTableEPT_RKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_
-__ZN3JSC9CodeBlock19addExceptionHandlerERKNS_11HandlerInfoE
-__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEmPKS2_
-__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERKNS_10IdentifierES2_
-__ZN3WTF6VectorIN3JSC18ControlFlowContextELm0EE14expandCapacityEmPKS2_
-__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitPopScopeEv
-__ZN3JSCL21arrayProtoFuncForEachEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC8JSObject3getEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC11Interpreter20prepareForRepeatCallEPNS_18FunctionExecutableEPNS_9ExecStateEPNS_10JSFunctionEiPNS_14ScopeChainNodeEPNS_7JSValueE
-__ZN3JSC17BytecodeGenerator11emitPostIncEPNS_10RegisterIDES2_
-__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_7JSValueE
-__ZN3JSC11Interpreter13endRepeatCallERNS_16CallFrameClosureE
-__ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateEj
-__ZN3JSC10JSFunction16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL25functionProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC10JSFunction9classInfoEv
-__ZNK3JSC7UStringixEi
-__ZNK3JSC18FunctionExecutable11paramStringEv
-__ZN3WTF6VectorItLm64EE6appendIcEEvPKT_m
-__ZN3JSC13StringBuilder7releaseEv
-__ZN3JSC10makeStringIPKcNS_7UStringES2_S3_S2_S3_EES3_T_T0_T1_T2_T3_T4_
-__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC17RegExpConstructor14arrayOfMatchesEPNS_9ExecStateE
-__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE
-__ZN3JSC7JSArrayC2EN3WTF17NonNullPassRefPtrINS_9StructureEEEj
-__ZN3JSC7JSArray19setLazyCreationDataEPv
-__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC7JSArray16lazyCreationDataEv
-__ZN3JSC18RegExpMatchesArray17fillArrayInstanceEPNS_9ExecStateE
-__ZN3JSC24RegExpConstructorPrivateD1Ev
-__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC8JSString14toThisJSStringEPNS_9ExecStateE
-__ZNK3JSC7UString30spliceSubstringsWithSeparatorsEPKNS0_5RangeEiPKS0_i
-__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL19arrayProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE
-__ZN3JSC4Heap15recordExtraCostEm
-__ZNK3JSC8JSObject3getEPNS_9ExecStateEj
-__ZN3JSC15ObjectPrototype18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC4Heap9markRootsEv
-__ZN3JSC4Heap30markStackObjectsConservativelyERNS_9MarkStackE
-__ZN3JSC4Heap31markCurrentThreadConservativelyERNS_9MarkStackE
-__ZN3JSC4Heap39markCurrentThreadConservativelyInternalERNS_9MarkStackE
-__ZN3JSC4Heap18markConservativelyERNS_9MarkStackEPvS3_
-__ZN3JSC9MarkStack5drainEv
-__ZN3JSC9MarkStack12markChildrenEPNS_6JSCellE
-__ZN3JSC8JSObject12markChildrenERNS_9MarkStackE
-__ZN3JSC14JSGlobalObject12markChildrenERNS_9MarkStackE
-__ZN3JSC9CodeBlock13markAggregateERNS_9MarkStackE
-__ZN3JSC18FunctionExecutable13markAggregateERNS_9MarkStackE
-__ZN3JSC10JSFunction12markChildrenERNS_9MarkStackE
-__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
-__ZN3JSC7JSArray18markChildrenDirectERNS_9MarkStackE
-__ZN3JSC15JSWrapperObject12markChildrenERNS_9MarkStackE
-__ZN3JSC18GlobalEvalFunction12markChildrenERNS_9MarkStackE
-__ZN3JSC12JSActivation12markChildrenERNS_9MarkStackE
-__ZN3JSC9Arguments12markChildrenERNS_9MarkStackE
-__ZN3JSCL12markIfNeededERNS_9MarkStackENS_7JSValueE
-__ZN3JSC4Heap20markProtectedObjectsERNS_9MarkStackE
-__ZN3JSC12SmallStrings12markChildrenERNS_9MarkStackE
-__ZN3JSC9MarkStack7compactEv
-__ZN3JSC4Heap12resizeBlocksEv
-__ZNK3JSC4Heap11markedCellsEmm
-__ZN3JSC17PrototypeFunctionD1Ev
-__ZN3JSC12RegExpObjectD1Ev
-__ZN3JSC8JSObjectD1Ev
-__ZN3JSC22JSPropertyNameIteratorD1Ev
-__ZN3WTF10RefCountedIN3JSC14StructureChainEE5derefEv
-__ZN3JSC12JSActivationD1Ev
-__ZN3JSC12JSActivation16JSActivationDataD1Ev
-__ZN3JSC16JSVariableObjectD2Ev
-__ZN3JSC23normalizePrototypeChainEPNS_9ExecStateENS_7JSValueES2_RKNS_10IdentifierERm
-__ZN3JSC9ArgumentsD1Ev
-__ZN3JSC9ArgumentsD2Ev
-__ZN3JSC18RegExpMatchesArrayD1Ev
-__ZNK3JSC7UString8toUInt32EPbb
-__ZNK3JSC7UString8toDoubleEbb
-__ZNK3JSC7UString10getCStringERN3WTF6VectorIcLm32EEE
-__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC17DeleteBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator15emitDeleteByValEPNS_10RegisterIDES2_S2_
-__ZN3JSC10MathObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC21getStaticFunctionSlotINS_8JSObjectEEEbPNS_9ExecStateEPKNS_9HashTableEPS1_RKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC13jsAddSlowCaseEPNS_9ExecStateENS_7JSValueES2_
-__ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
-__ZN3JSC14NumericStrings3addEd
-__ZN3JSC7UString4fromEd
-__ZN3WTF32doubleToStringInJavaScriptFormatEdPcPj
-__ZN3WTF4dtoaEPcdiPiS1_PS0_
-__ZN3WTFL4multERNS_6BigIntERKS0_
-__ZN3WTF6VectorIjLm16EEaSERKS1_
-__ZN3WTF6BigInt6appendEj
-__ZN3JSC7UStringC1EPKci
-__ZN3JSCL20stringProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC8JSString11resolveRopeEPNS_9ExecStateE
-__ZN3JSC8JSStringC2EPNS_12JSGlobalDataEjPS0_S3_
-__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC12ContinueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14continueTargetERKNS_10IdentifierE
-__ZN3JSC13DeleteDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14emitDeleteByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3JSC10JSFunction14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC15IdentifierArena21makeNumericIdentifierEPNS_12JSGlobalDataEd
-__ZN3JSC11Interpreter7executeERNS_16CallFrameClosureEPNS_7JSValueE
-__ZN3JSC9Arguments13copyRegistersEv
-__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC24ApplyFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC14ExpressionNode13isSimpleArrayEv
-__ZN3JSC17BytecodeGenerator26emitJumpIfNotFunctionApplyEPNS_10RegisterIDEPNS_5LabelE
-__ZN3JSC17BytecodeGenerator22willResolveToArgumentsERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator29uncheckedRegisterForArgumentsEv
-__ZN3JSC17BytecodeGenerator15emitLoadVarargsEPNS_10RegisterIDES2_
-__ZN3JSC17BytecodeGenerator15emitCallVarargsEPNS_10RegisterIDES2_S2_S2_jjj
-__ZN3JSC14InstanceOfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14emitInstanceOfEPNS_10RegisterIDES2_S2_S2_
-__ZN3JSCL27isInvalidParamForInstanceOfEPNS_9ExecStateEPNS_9CodeBlockEPKNS_11InstructionENS_7JSValueERS7_
-__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_7JSValueES3_
-__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE
-__ZN3JSCL21arrayProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC8JSString12toThisObjectEPNS_9ExecStateE
-__ZN3JSC12StringObjectC1EN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_8JSStringE
-__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
-__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
-__ZNK3JSC8JSObject11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
-__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
-__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
-__ZN3JSCL23stringProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC12StringObject9classInfoEv
-__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE
-__ZN3JSC16ErrorConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL29constructWithErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC14constructErrorEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC13ErrorInstanceC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZL14makePrefixNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeENS_8OperatorEiii
-__ZNK3JSC7AddNode5isAddEv
-__ZN3JSC12BinaryOpNode10emitStrcatERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_PNS_21ReadModifyResolveNodeE
-__ZNK3JSC10StringNode8isStringEv
-__ZNK3JSC14ExpressionNode8isStringEv
-__ZN3JSC17BytecodeGenerator15emitToPrimitiveEPNS_10RegisterIDES2_
-__ZN3JSC17BytecodeGenerator10emitStrcatEPNS_10RegisterIDES2_i
-__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC8JSString40appendValueInConstructAndIncrementLengthEPNS_9ExecStateERjNS_7JSValueE
-__ZN3JSC17ProgramExecutableD0Ev
-__ZN3JSC16ProgramCodeBlockD0Ev
-__ZN3JSC15GlobalCodeBlockD2Ev
-__ZN3WTF9HashTableIPN3JSC15GlobalCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
-__ZN3JSC9CodeBlock8RareDataD2Ev
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS1_INS2_14EvalExecutableEEEENS_18PairFirstExtractorIS8_EENS_7StrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSE_IS7_EEEESF_E15deallocateTableEPS8_i
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS1_INS2_14EvalExecutableEEEENS_18PairFirstExtractorIS8_EENS_7StrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSE_IS7_EEEESF_E4findIS4_NS_22IdentityHashTranslatorIS4_S8_SC_EEEENS_17HashTableIteratorIS4_S8_SA_SC_SH_SF_EERKT_
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS1_INS2_14EvalExecutableEEEENS_18PairFirstExtractorIS8_EENS_7StrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSE_IS7_EEEESF_E6rehashEi
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS1_INS2_14EvalExecutableEEEENS_18PairFirstExtractorIS8_EENS_7StrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSE_IS7_EEEESF_E3addIPS3_S7_NS_29RefPtrHashMapRawKeyTranslatorISK_S8_SH_SC_EEEES5_INS_17HashTableIteratorIS4_S8_SA_SC_SH_SF_EEbERKT_RKT0_
-__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EED1Ev
-__ZN3JSC6RegExpD1Ev
-__Z12jsRegExpFreeP8JSRegExp
-__ZN3JSC5Lexer19shiftLineTerminatorEv
-__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE
-__ZNK3JSC7UString8toDoubleEv
-__ZNK3JSC7ArgList8getSliceEiRS0_
-__ZN3JSC17RegExpConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL30constructWithRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC15constructRegExpEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC18globalFuncUnescapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3WTF6VectorItLm64EE14expandCapacityEmPKt
-__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm8EE14expandCapacityEmPKS3_
-__ZN3JSC10JSFunction4callEPNS_9ExecStateENS_7JSValueERKNS_7ArgListE
-__ZN3JSC11Interpreter7executeEPNS_18FunctionExecutableEPNS_9ExecStateEPNS_10JSFunctionEPNS_8JSObjectERKNS_7ArgListEPNS_14ScopeChainNodeEPNS_7JSValueE
-__ZL11makeDivNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
-__ZNK3JSC8NullNode6isNullEv
-__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC13constructDateEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC12DateInstanceC1EPNS_9ExecStateEd
-__ZN3WTF8timeClipEd
-__ZN3JSC13DatePrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL19dateProtoFuncGetDayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC12DateInstance9classInfoEv
-__ZNK3JSC12DateInstance26calculateGregorianDateTimeEPNS_9ExecStateE
-__ZN3JSC17DateInstanceCache3addEd
-__ZN3JSC21msToGregorianDateTimeEPNS_9ExecStateEdbRNS_17GregorianDateTimeE
-__ZN3JSC12getUTCOffsetEPNS_9ExecStateE
-__ZN3JSCL12getDSTOffsetEPNS_9ExecStateEdd
-__ZN3WTFL18calculateDSTOffsetEdd
-__ZN3WTF23dayInMonthFromDayInYearEib
-__ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC14NumericStrings3addEi
-__ZN3JSC7UString4fromEi
-__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC8JSString4Rope20destructNonRecursiveEv
-__ZNK3JSC19JSStaticScopeObject14isDynamicScopeEv
-__ZN3JSC17ReadModifyDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC18BooleanConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL22callBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZL17bracketIsAnchoredPKh
-__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E3addIS3_S3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEESt4pairINS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EEbERKT_RKT0_
-__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3WTF6VectorItLm256EE14expandCapacityEmPKt
-__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
-__ZN3JSC19FunctionConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL32constructWithFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
-__ZN3JSC8WithNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator13emitPushScopeEPNS_10RegisterIDE
-__ZN3JSC11Interpreter7resolveEPNS_9ExecStateEPNS_11InstructionERNS_7JSValueE
-__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC10SwitchNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC13CaseBlockNode20emitBytecodeForBlockERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_
-__ZN3JSC13CaseBlockNode18tryOptimizedSwitchERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERiS7_
-__ZN3JSCL17processClauseListEPNS_14ClauseListNodeERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERNS_10SwitchKindERbRiSB_
-__ZN3JSC17BytecodeGenerator11beginSwitchEPNS_10RegisterIDENS_10SwitchInfo10SwitchTypeE
-__ZN3WTF6VectorIN3JSC10SwitchInfoELm0EE14expandCapacityEm
-__ZN3WTF6VectorISt4pairIiiELm8EE14expandCapacityEmPKS2_
-__ZN3JSC17BytecodeGenerator9endSwitchEjPN3WTF6RefPtrINS_5LabelEEEPPNS_14ExpressionNodeEPS3_ii
-__ZN3JSC9CodeBlock24addStringSwitchJumpTableEv
-__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14expandCapacityEmPKS2_
-__ZN3WTF11VectorMoverILb0EN3JSC15StringJumpTableEE4moveEPKS2_S5_PS2_
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS2_14OffsetLocationEENS_18PairFirstExtractorIS7_EENS_7StrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSD_IS6_EEEESE_E6rehashEi
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS2_14OffsetLocationEENS_18PairFirstExtractorIS7_EENS_7StrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSD_IS6_EEEESE_E4findIS4_NS_22IdentityHashTranslatorIS4_S7_SB_EEEENS_17HashTableIteratorIS4_S7_S9_SB_SG_SE_EERKT_
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS2_14OffsetLocationEENS_18PairFirstExtractorIS7_EENS_7StrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSD_IS6_EEEESE_E3addIS4_S7_NS_22IdentityHashTranslatorIS4_S7_SB_EEEES5_INS_17HashTableIteratorIS4_S7_S9_SB_SG_SE_EEbERKT_RKT0_
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC11UStringImplEEESt4pairIS4_NS2_14OffsetLocationEENS_18PairFirstExtractorIS7_EENS_7StrHashIS4_EENS_14PairHashTraitsINS_10HashTraitsIS4_EENSD_IS6_EEEESE_E3addIPS3_S6_NS_29RefPtrHashMapRawKeyTranslatorISJ_S7_SG_SB_EEEES5_INS_17HashTableIteratorIS4_S7_S9_SB_SG_SE_EEbERKT_RKT0_
-__ZN3JSC15StringJumpTable14offsetForValueEPNS_11UStringImplEi
-__ZN3JSC28globalFuncEncodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL6encodeEPNS_9ExecStateERKNS_7ArgListEPKc
-__ZNK3JSC7UString10UTF8StringEb
-__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
-__ZN3JSC7CStringD1Ev
-__ZN3JSC11Interpreter22resolveBaseAndPropertyEPNS_9ExecStateEPNS_11InstructionERNS_7JSValueE
-__ZN3JSCL24regExpConstructorDollar2EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar3EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar4EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
-__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEPNS_9ExecStateEj
-__ZN3JSC9CodeBlock34reparseForExceptionInfoIfNecessaryEPNS_9ExecStateE
-__ZN3JSC18FunctionExecutable20reparseExceptionInfoEPNS_12JSGlobalDataEPNS_14ScopeChainNodeEPNS_9CodeBlockE
-__ZN3WTF6OwnPtrIN3JSC13ExceptionInfoEE3setEPS2_
-__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm16EE14expandCapacityEmPKS3_
-__ZN3JSC8jsLessEqEPNS_9ExecStateENS_7JSValueES2_
-__ZN3WTF6VectorIN3JSC8JSString4Rope5FiberELm32EE14expandCapacityEm
-__ZL12makeMultNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
-__ZN3JSCL17mathProtoFuncCeilEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC7JSValue17toPrimitiveStringEPNS_9ExecStateE
-__ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitCallEvalEPNS_10RegisterIDES2_S2_PNS_13ArgumentsNodeEjjj
-__ZN3JSC15globalFuncIsNaNEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEiiRNS_7JSValueE
-__ZN3JSC13LiteralParser5Lexer3lexERNS1_18LiteralParserTokenE
-__ZN3JSC13LiteralParser5parseENS0_11ParserStateE
-__ZN3JSC20MarkedArgumentBufferD1Ev
-__ZN3JSC13EvalCodeCache3getEPNS_9ExecStateERKNS_7UStringEPNS_14ScopeChainNodeERNS_7JSValueE
-__ZN3JSC14EvalExecutable7compileEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPiPNS_7UStringE
-__ZN3JSC8EvalNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16FunctionBodyNodeELm0EEERKNS_10SourceCodeEji
-__ZNK3JSC10ScopeChain10localDepthEv
-__ZN3JSC13EvalCodeBlockC2EPNS_14EvalExecutableEPNS_14JSGlobalObjectEN3WTF10PassRefPtrINS_14SourceProviderEEEi
-__ZN3JSC17BytecodeGeneratorC1EPNS_8EvalNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_11UStringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISD_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE
-__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_11UStringImplEEENS_16SymbolTableEntryENS_17IdentifierRepHashENS9_10HashTraitsISD_EENS_26SymbolTableIndexHashTraitsEEEPNS_13EvalCodeBlockE
-__ZN3JSC8EvalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZThn12_N3JSC8EvalNodeD0Ev
-__ZN3WTF29RefPtrHashMapRawKeyTranslatorIPN3JSC11UStringImplESt4pairINS_6RefPtrIS2_EENS5_INS1_14EvalExecutableEEEENS_14PairHashTraitsINS_10HashTraitsIS6_EENSB_IS8_EEEENS_7StrHashIS6_EEE9translateERS9_S3_RKS8_
-__ZN3JSC9ExecState9thisValueEv
-__ZN3JSC11Interpreter7executeEPNS_14EvalExecutableEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeEPNS_7JSValueE
-__ZN3JSC11Interpreter11resolveBaseEPNS_9ExecStateEPNS_11InstructionE
-__ZN3JSC16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL26stringProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC7JSValue20toIntegerPreserveNaNEPNS_9ExecStateE
-__ZNK3JSC7UString5rfindERKS0_i
-__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC14EvalExecutableD0Ev
-__ZN3JSC13EvalCodeBlockD0Ev
-__ZN3WTF21CrossThreadRefCountedINS_16OwnFastMallocPtrItEEE5derefEv
-__ZN3JSC10JSONObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL22JSONProtoFuncStringifyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC11StringifierC2EPNS_9ExecStateENS_7JSValueES3_
-__ZN3JSCL20unwrapBoxedPrimitiveEPNS_9ExecStateENS_7JSValueE
-__ZN3JSC11Stringifier9stringifyENS_7JSValueE
-__ZN3JSC11Stringifier22appendStringifiedValueERNS_13StringBuilderENS_7JSValueEPNS_8JSObjectERKNS_27PropertyNameForFunctionCallE
-__ZN3JSC11Stringifier6toJSONENS_7JSValueERKNS_27PropertyNameForFunctionCallE
-__ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE
-__ZN3JSC11Stringifier6Holder18appendNextPropertyERS0_RNS_13StringBuilderE
-__ZN3JSC11Stringifier6indentEv
-__ZNK3JSC7UString6substrEii
-__ZNK3JSC11Stringifier12startNewLineERNS_13StringBuilderE
-__ZN3JSC11Stringifier18appendQuotedStringERNS_13StringBuilderERKNS_7UStringE
-__ZN3JSC11Stringifier8unindentEv
-__ZN3JSC11StringifierD2Ev
-__ZN3JSC19JSStaticScopeObject12markChildrenERNS_9MarkStackE
-__ZN3JSC17PrefixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSCL18JSONProtoFuncParseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC13LiteralParser5Lexer9lexStringILNS0_10ParserModeE0EEENS0_9TokenTypeERNS1_18LiteralParserTokenE
-__ZN3JSC13LiteralParser5Lexer9lexNumberERNS1_18LiteralParserTokenE
-__ZN3JSC14LogicalNotNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b
-__ZN3JSCL18regExpObjectSourceEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL19stringProtoFuncTrimEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL10trimStringEPNS_9ExecStateENS_7JSValueEi
-__ZN3JSC15isStrWhiteSpaceEt
-__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callStringConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC23FunctionCallBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC14jsIsObjectTypeENS_7JSValueE
-__ZN3JSC14StructureChainD1Ev
-__ZN3WTF11OwnArrayPtrINS_6RefPtrIN3JSC9StructureEEEE10safeDeleteEv
-__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_7JSValueEjb
-__ZNK3JSC8JSObject22isNotAnObjectErrorStubEv
-__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEPNS_9ExecStateEjRiS3_S3_
-__ZN3JSC9CodeBlock43hasGlobalResolveInstructionAtBytecodeOffsetEj
-__ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
-__ZNK3JSC8JSObject19isWatchdogExceptionEv
-__ZN3JSC9CodeBlock24handlerForBytecodeOffsetEj
-__ZN3JSC11Interpreter15unwindCallFrameERPNS_9ExecStateENS_7JSValueERjRPNS_9CodeBlockE
-__ZNK3JSC12JSActivation9classInfoEv
-__ZN3JSC11Interpreter20createExceptionScopeEPNS_9ExecStateEPKNS_11InstructionE
-__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC4Heap17collectAllGarbageEv
-__ZN3JSC4Heap5sweepEv
-__ZN3JSC12StringObjectD1Ev
-__ZN3JSC15JSWrapperObjectD2Ev
-__ZN3JSC19JSStaticScopeObjectD1Ev
-__ZN3JSC19JSStaticScopeObjectD2Ev
-__ZN3JSC12DateInstanceD1Ev
-__ZN3JSC14JSGlobalObjectD2Ev
-__ZN3JSC17FunctionPrototypeD1Ev
-__ZN3JSC15ObjectPrototypeD1Ev
-__ZN3JSC14ArrayPrototypeD1Ev
-__ZN3JSC15StringPrototypeD1Ev
-__ZN3JSC16BooleanPrototypeD1Ev
-__ZN3JSC15NumberPrototypeD1Ev
-__ZN3JSC13DatePrototypeD1Ev
-__ZN3JSC15RegExpPrototypeD1Ev
-__ZN3JSC14ErrorPrototypeD1Ev
-__ZN3JSC13ErrorInstanceD2Ev
-__ZN3JSC20NativeErrorPrototypeD1Ev
-__ZN3JSC17ObjectConstructorD1Ev
-__ZN3JSC19FunctionConstructorD1Ev
-__ZN3JSC16ArrayConstructorD1Ev
-__ZN3JSC17StringConstructorD1Ev
-__ZN3JSC18BooleanConstructorD1Ev
-__ZN3JSC17NumberConstructorD1Ev
-__ZN3JSC15DateConstructorD1Ev
-__ZN3JSC17RegExpConstructorD1Ev
-__ZN3JSC16ErrorConstructorD1Ev
-__ZN3JSC22NativeErrorConstructorD1Ev
-__ZN3JSC10MathObjectD1Ev
-__ZN3JSC10JSONObjectD1Ev
-__ZN3JSC18GlobalEvalFunctionD1Ev
-__ZN3JSC7JSArray15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
-__ZN3JSC11DoWhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC11Interpreter14uncachePutByIDEPNS_9CodeBlockEPNS_11InstructionE
-__ZN3JSC9parseDateEPNS_9ExecStateERKNS_7UStringE
-__ZN3JSC37parseDateFromNullTerminatedCharactersEPNS_9ExecStateEPKc
-__ZN3WTFL37parseDateFromNullTerminatedCharactersEPKcRbRi
-__ZN3JSCL21dateProtoFuncSetHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL23setNewValueFromTimeArgsEPNS_9ExecStateENS_7JSValueERKNS_7ArgListEib
-__ZN3JSC21gregorianDateTimeToMSEPNS_9ExecStateERKNS_17GregorianDateTimeEdb
-__ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC21UntypedPtrAndBitfieldanEm
-__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC18globalFuncParseIntEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC15toInt32SlowCaseEdRb
-__ZN3JSCL19regExpProtoFuncExecEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC12RegExpObject4execEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC9CodeBlock27addImmediateSwitchJumpTableEv
-__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE15reserveCapacityEm
-__ZN3WTF6VectorIiLm0EE4fillERKim
-__ZN3JSC15SimpleJumpTable14offsetForValueEii
-__ZN3JSCL29objectProtoFuncHasOwnPropertyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC8JSObject14hasOwnPropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC17NumberConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callNumberConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
-__ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
-__ZN3JSCL22arrayProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC7UString12replaceRangeEiiRKS0_
-__ZN3JSC28globalFuncDecodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL6decodeEPNS_9ExecStateERKNS_7ArgListEPKcb
-__ZN3JSC17BytecodeGenerator10emitPreDecEPNS_10RegisterIDE
-__ZN3JSCL8parseIntERKNS_7UStringEi
-__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
-__ZN3JSC26createNotAnObjectErrorStubEPNS_9ExecStateEb
-__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZNK3JSC22JSNotAnObjectErrorStub22isNotAnObjectErrorStubEv
-__ZN3JSC22createNotAnObjectErrorEPNS_9ExecStateEPNS_22JSNotAnObjectErrorStubEjPNS_9CodeBlockE
-__ZN3JSC9CodeBlock37getByIdExceptionInfoForBytecodeOffsetEPNS_9ExecStateEjRNS_8OpcodeIDE
-__ZN3JSCL18createErrorMessageEPNS_9ExecStateEPNS_9CodeBlockEiiiNS_7JSValueENS_7UStringE
-__ZN3JSC10makeStringIPKcNS_7UStringES2_S3_S2_S3_S2_EES3_T_T0_T1_T2_T3_T4_T5_
-__ZN3JSC5Error6createEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEilS6_
-__ZN3JSC22NativeErrorConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
-__ZN3JSCL35constructWithNativeErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC22NativeErrorConstructor9constructEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL24dateProtoFuncToGMTStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC12DateInstance29calculateGregorianDateTimeUTCEPNS_9ExecStateE
-__ZN3JSC20formatDateUTCVariantERKNS_17GregorianDateTimeERA100_c
-__ZN3JSC13formatTimeUTCERKNS_17GregorianDateTimeERA100_c
-__ZN3JSC10makeStringIPcPKcS1_EENS_7UStringET_T0_T1_
-__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL28substituteBackreferencesSlowERKNS_7UStringES2_PKiPNS_6RegExpEi
-__ZN3JSCL21dateProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC10formatDateERKNS_17GregorianDateTimeERA100_c
-__ZN3JSC10formatTimeERKNS_17GregorianDateTimeERA100_c
-__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
-__ZN3JSCL20dateProtoFuncGetDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC21ReadModifyBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZL17makeLeftShiftNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
-__ZL18makeRightShiftNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
-__ZN3JSCL25stringProtoFuncCharCodeAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC17RegExpConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL21callRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC22JSNotAnObjectErrorStubD1Ev
-__ZN3JSC13JSNotAnObjectD1Ev
-__ZN3JSC13ErrorInstanceD1Ev
-__ZN3JSC17ObjectConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL30constructWithObjectConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3WTF9HashTableIdSt4pairIdN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E4findIdNS_22IdentityHashTranslatorIdS4_S8_EEEENS_17HashTableIteratorIdS4_S6_S8_SD_SB_EERKT_
-__ZN3WTF9HashTableIdSt4pairIdN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E6rehashEi
-__ZN3WTF9HashTableIdSt4pairIdN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsIdEENSA_IS3_EEEESB_E3addIdS3_NS_17HashMapTranslatorIS4_SD_S8_EEEES1_INS_17HashTableIteratorIdS4_S6_S8_SD_SB_EEbERKT_RKT0_
-__ZN3JSC21UntypedPtrAndBitfieldoREm
-__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringE
-__ZN3JSC17PropertyNameArray3addEPNS_11UStringImplE
-__ZN3JSCL22objectProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE
-__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
-__ZN3JSC12StringObjectC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7UStringE
-__ZN3JSC12RegExpObject11getCallDataERNS_8CallDataE
-__ZN3JSC8VoidNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC15constructNumberEPNS_9ExecStateENS_7JSValueE
-__ZNK3JSC12NumberObject9classInfoEv
-__ZN3JSC12NumberObjectD1Ev
-__ZN3JSC4Heap9freeBlockEm
-__ZN3JSC4Heap12freeBlockPtrEPNS_14CollectorBlockE
-__ZN3JSCL20arrayProtoFuncSpliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL18arrayProtoFuncSortEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC7JSArray4sortEPNS_9ExecStateE
-__ZN3JSC7JSArray17compactForSortingEv
-__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC9Structure27despecifyDictionaryFunctionERKNS_10IdentifierE
-__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC23jsSingleCharacterStringEPNS_12JSGlobalDataEt
-__ZN3WTF6VectorIN3JSC7UString5RangeELm16EE15reserveCapacityEm
-__ZN3WTF6VectorIN3JSC7UStringELm16EE15reserveCapacityEm
-__ZN3JSC19globalFuncEncodeURIEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC9ArrayNode13isSimpleArrayEv
-__ZNK3JSC9ArrayNode14toArgumentListEPNS_12JSGlobalDataE
-__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC7JSArray3popEv
-__ZN3WTF6VectorIPN3JSC9StructureELm8EE14expandCapacityEmPKS3_
-__ZNK3JSC9Arguments20numProvidedArgumentsEPNS_9ExecStateE
-__ZN3JSC9Arguments15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
-__ZN3JSC12RegExpObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC9lookupPutINS_12RegExpObjectEEEbPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEPKNS_9HashTableEPT_
-__ZN3JSCL24setRegExpObjectLastIndexEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
-__Z15jsc_pcre_xclassiPKh
-__ZN3JSC18PostfixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSCL28regExpConstructorLeftContextEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateEjNS_7JSValueE
-__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC36constructBooleanFromImmediateBooleanEPNS_9ExecStateENS_7JSValueE
-__ZN3JSC13BooleanObjectC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
-__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierEjPNS_9CodeBlockE
-__ZN3JSC10makeStringIPKcNS_7UStringEEES3_T_T0_
-__ZN3JSCL22errorProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC10makeStringINS_7UStringEPKcS1_EES1_T_T0_T1_
-__ZN3JSCL16mathProtoFuncAbsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC6JSCell9getObjectEv
-__ZN3JSC9MarkStack12releaseStackEPvm
-__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
-__ZNK3JSC8JSObject21findPropertyHashEntryEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC13BooleanObjectD1Ev
-__ZN3JSC22JSPropertyNameIterator12markChildrenERNS_9MarkStackE
-__ZN3JSCL21arrayProtoFuncUnShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC26jsSingleCharacterSubstringEPNS_12JSGlobalDataERKNS_7UStringEj
-__ZN3JSC13UnaryPlusNode14stripUnaryPlusEv
-__ZN3JSC8JSString18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
-__ZN3JSC9Arguments3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC9LabelNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSCL21stringProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL24booleanProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL9dateParseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC10JSFunction19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E3addIS3_S3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEESt4pairINS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EEbERKT_RKT0_
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3JSC11Interpreter11resolveSkipEPNS_9ExecStateEPNS_11InstructionERNS_7JSValueE
-__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3WTF7Unicode18UTF8SequenceLengthEc
-__ZN3WTF7Unicode18decodeUTF8SequenceEPKc
-__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_7JSValueEjPNS_9CodeBlockE
-__ZN3JSCL24dateProtoFuncGetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC16ArrayConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL20callArrayConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC7JSArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
-__ZN3WTF9HashTableIPN3JSC11UStringImplES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
-__ZN3JSC9ExecState10arrayTableEPS0_
-__ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC13LiteralParser5Lexer9lexStringILNS0_10ParserModeE1EEENS0_9TokenTypeERNS1_18LiteralParserTokenE
-__ZN3WTFL3i2bERNS_6BigIntEi
-__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZNK3JSC8JSString8toObjectEPNS_9ExecStateE
-__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
-__ZN3WTFL3b2dERKNS_6BigIntEPi
-__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE14expandCapacityEmPKS4_
-__ZN3JSC7JSArray4sortEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE
-__ZN3WTF6VectorIN3JSC26AVLTreeNodeForArrayCompareELm0EE6resizeEm
-__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE6insertEi
-__ZN3JSC32AVLTreeAbstractorForArrayCompare15compare_key_keyENS_7JSValueES1_
-__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE7balanceEi
-__ZN3JSCL22numberProtoFuncToFixedEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL16integerPartNoExpEd
-__ZN3JSC10makeStringINS_7UStringES1_PKcS1_EES1_T_T0_T1_T2_
-__ZN3JSCL16mathProtoFuncLogEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL16mathProtoFuncPowEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3WTF13tryFastCallocEmm
-__ZN3WTF10fastCallocILb0EEEPvmm
-__ZN3JSC7JSArray11sortNumericEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE
-__ZN3JSCL22compareNumbersForQSortEPKvS1_
-__ZN3JSC10makeStringINS_7UStringES1_EES1_T_T0_
-__ZN3WTF6VectorIPN3JSC10RegisterIDELm32EE14expandCapacityEmPKS3_
-__ZN3JSC16ErrorConstructor11getCallDataERNS_8CallDataE
-__ZN3JSCL20callErrorConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL21stringProtoFuncSearchEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL17arrayProtoFuncMapEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC7JSValue16synthesizeObjectEPNS_9ExecStateE
-__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd
-__ZN3JSCL7dateNowEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC18globalFuncIsFiniteEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC17DeleteResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZNK3JSC21UStringSourceProvider8getRangeEii
-__ZN3JSC12JSActivation14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSCL22numberProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL16mathProtoFuncCosEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC12JSGlobalData6createEv
-__ZN3JSC8JSObject17putDirectFunctionEPNS_9ExecStateEPNS_16InternalFunctionEj
-__ZN3JSC12JSGlobalData13startSamplingEv
-__ZN3JSC11Interpreter13startSamplingEv
-__ZN3JSC12JSGlobalData12stopSamplingEv
-__ZN3JSC11Interpreter12stopSamplingEv
-__ZN3JSCL17mathProtoFuncSqrtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL16mathProtoFuncSinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC16toUInt32SlowCaseEdRb
-__ZN3JSC9CodeBlock27addCharacterSwitchJumpTableEv
-__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
-__ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E3addIS3_S3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEESt4pairINS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EEbERKT_RKT0_
-__ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
-__ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_22IdentityHashTranslatorIS3_S3_S7_EEEENS_17HashTableIteratorIS3_S3_S5_S7_S9_S9_EERKT_
-__ZN3JSC15ObjectPrototype3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSCltERKNS_7UStringES2_
-__ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE
-__ZN3JSC11Interpreter14dumpSampleDataEPNS_9ExecStateE
-__ZN3JSC4Heap7destroyEv
-__ZN3JSC4Heap10freeBlocksEv
-__ZN3JSC14JSGlobalObject25destroyJSGlobalObjectDataEPv
-__ZN3JSC14JSGlobalObject18JSGlobalObjectDataD2Ev
-__ZN3JSC12JSGlobalDataD1Ev
-__ZN3JSC12JSGlobalDataD2Ev
-__ZN3JSC12RegisterFileD1Ev
-__ZNK3JSC9HashTable11deleteTableEv
-__ZN3JSC5LexerD1Ev
-__ZN3JSC17CommonIdentifiersD2Ev
-__ZN3JSC21deleteIdentifierTableEPNS_15IdentifierTableE
-__ZN3JSC15IdentifierTableD2Ev
-__ZN3JSC4HeapD1Ev
-__ZN3JSC14NumericStringsD1Ev
-__ZN3JSC12SmallStringsD1Ev
index d6f6caabe527736b07e8d4782a8148a3b54b3e92..3cb3d1dc440dc2fe5e444548f5f4eaadd50cd913 100644 (file)
 __ZN3WTF10fastMallocEm
 __ZN3WTF10fastMallocEm
-__ZN3WTF10fastMallocILb1EEEPvm
 __ZN3WTF20TCMalloc_ThreadCache10InitModuleEv
 __ZN3WTFL15InitSizeClassesEv
 __Z20TCMalloc_SystemAllocmPmm
 __ZN3WTFL13MetaDataAllocEm
 __ZN3WTF20TCMalloc_ThreadCache10InitModuleEv
 __ZN3WTFL15InitSizeClassesEv
 __Z20TCMalloc_SystemAllocmPmm
 __ZN3WTFL13MetaDataAllocEm
+__ZN3WTF17TCMalloc_PageHeap19initializeScavengerEv
 __ZN3WTF20TCMalloc_ThreadCache22CreateCacheIfNecessaryEv
 __ZN3WTF25TCMalloc_Central_FreeList11RemoveRangeEPPvS2_Pi
 __ZN3WTF25TCMalloc_Central_FreeList18FetchFromSpansSafeEv
 __ZN3WTF17TCMalloc_PageHeap10AllocLargeEm
 __ZN3WTF17TCMalloc_PageHeap8GrowHeapEm
 __ZN3WTF20TCMalloc_ThreadCache22CreateCacheIfNecessaryEv
 __ZN3WTF25TCMalloc_Central_FreeList11RemoveRangeEPPvS2_Pi
 __ZN3WTF25TCMalloc_Central_FreeList18FetchFromSpansSafeEv
 __ZN3WTF17TCMalloc_PageHeap10AllocLargeEm
 __ZN3WTF17TCMalloc_PageHeap8GrowHeapEm
+__ZN3WTF17TCMalloc_PageHeap6DeleteEPNS_4SpanE
+__ZN3WTF8fastFreeEPv
 __ZN3WTF19initializeThreadingEv
 __ZN3WTF19initializeThreadingEv
-__ZN3WTF20initializeMainThreadEv
-__ZN3WTF5MutexC1Ev
-__ZN3WTF28initializeMainThreadPlatformEv
 __ZN3WTF36lockAtomicallyInitializedStaticMutexEv
 __ZN3WTF36lockAtomicallyInitializedStaticMutexEv
-__ZN3WTF8fastFreeEPv
 __ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
 __ZN3JSC19initializeThreadingEv
 __ZN3JSCL23initializeThreadingOnceEv
 __ZN3WTF38unlockAtomicallyInitializedStaticMutexEv
 __ZN3JSC19initializeThreadingEv
 __ZN3JSCL23initializeThreadingOnceEv
+__ZN3WTF13WTFThreadDataC1Ev
 __ZN3JSC17initializeUStringEv
 __ZN3JSC17initializeUStringEv
-__ZN3JSC12initDateMathEv
+__ZN7WebCore10StringImpl5emptyEv
+__ZN3JSC12JSGlobalData10storeVPtrsEv
+__ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoEj
+__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3WTF16fastZeroedMallocEm
+__ZN3JSC7JSArrayD1Ev
+__ZN3JSC7JSArrayD2Ev
+__ZN3JSC9StructureD1Ev
+__ZN3JSC9StructureD2Ev
+__ZN3JSC11JSByteArray15createStructureENS_7JSValueE
+__ZN3JSC11JSByteArrayD1Ev
+__ZN3JSC8JSStringD1Ev
+__ZN3JSC10JSFunctionC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC10JSFunctionC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC10JSFunctionD1Ev
+__ZN3JSC10JSFunctionD2Ev
+__ZN3JSC18VPtrHackExecutableD0Ev
+__ZN3WTF5MutexC1Ev
+__ZN3WTF15initializeDatesEv
 __ZN3WTF11currentTimeEv
 __ZN3WTF11currentTimeEv
+__ZN3WTF8msToYearEd
+__ZN3WTF39initializeMainThreadToProcessMainThreadEv
+__ZN3WTFL43initializeMainThreadToProcessMainThreadOnceEv
+__ZN3WTF47initializeMainThreadToProcessMainThreadPlatformEv
+__ZN3WTF20initializeMainThreadEv
 __ZN3WTF15ThreadConditionC1Ev
 __ZN3WTF15ThreadConditionC1Ev
+__ZN7WebCore10StringImpl6createEPKtj
+__ZN7WebCore10StringImpl19createUninitializedEjRPt
 __ZN3WTF5Mutex4lockEv
 __ZN3WTF5Mutex6unlockEv
 __ZN3WTF5Mutex4lockEv
 __ZN3WTF5Mutex6unlockEv
+__ZNK7WebCore6String17crossThreadStringEv
+__ZN7WebCore10StringImpl17crossThreadStringEv
+__ZN7WebCore10StringImpl12sharedBufferEv
+__ZN7WebCore6StringC1EPKc
+__ZN7WebCore10StringImpl6createEPKc
+__ZN7WebCore10StringImpl6createEPKcj
+__ZNK7WebCore6String14threadsafeCopyEv
+__ZNK7WebCore10StringImpl14threadsafeCopyEv
+__ZN7WebCore10StringImpl8endsWithEPS0_b
+__ZN7WebCore10StringImpl4findEPS0_ib
+__ZN7WebCore10StringImplD1Ev
+__ZN7WebCore10StringImplD2Ev
+__ZN7WebCoreplERKNS_6StringEPKc
+__ZN7WebCore6String6appendERKS0_
+__ZN7WebCoreplERKNS_6StringES2_
 __ZN3WTF12createThreadEPFPvS0_ES0_PKc
 __ZN3WTF20createThreadInternalEPFPvS0_ES0_PKc
 __ZN3WTF12createThreadEPFPvS0_ES0_PKc
 __ZN3WTF20createThreadInternalEPFPvS0_ES0_PKc
-__ZN3WTFL35establishIdentifierForPthreadHandleERP17_opaque_pthread_t
+__ZN3WTFL35establishIdentifierForPthreadHandleERKP17_opaque_pthread_t
 __ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTrai
 __ZN3WTFL16threadEntryPointEPv
 __ZN3WTF9HashTableIjSt4pairIjP17_opaque_pthread_tENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTrai
 __ZN3WTFL16threadEntryPointEPv
-__ZN3WTF16fastZeroedMallocEm
-__ZN3WTF21setThreadNameInternalEPKc
+__ZN3WTF31initializeCurrentThreadInternalEPKc
+__ZN3WTF20ThreadIdentifierData10initializeEj
+__ZN3WTF20ThreadIdentifierData23initializeKeyOnceHelperEv
 __ZN3WTF5MutexD1Ev
 __ZN3WTF5MutexD1Ev
-__ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i
-__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv
 __ZN3WTF12isMainThreadEv
 __ZN3WTF12isMainThreadEv
+__ZN3WTF7CString16newUninitializedEmRPc
+__ZNK3WTF7CString4dataEv
 __ZN3WTF14FastMallocZone4sizeEP14_malloc_zone_tPKv
 __ZN3WTF14FastMallocZone4sizeEP14_malloc_zone_tPKv
+__ZN7WebCore6String29charactersWithNullTerminationEv
+__ZN7WebCore10StringImpl34createWithTerminatingNullCharacterERKS0_
 __ZN3WTF13currentThreadEv
 __ZN3WTF13currentThreadEv
+__ZN3WTF20ThreadIdentifierData10identifierEv
+__ZNK7WebCore6String15stripWhiteSpaceEv
+__ZN7WebCore10StringImpl15stripWhiteSpaceEv
+__ZN7WebCore5equalEPKNS_10StringImplES2_
+__ZN7WebCoreplEPKcRKNS_6StringE
+__ZN7WebCore6StringC1EPKt
+__ZN7WebCore6StringC2EPKt
+__ZNK7WebCore6String7isEmptyEv
 __ZN3WTF16callOnMainThreadEPFvPvES0_
 __ZN3WTF5DequeINS_19FunctionWithContextEE14expandCapacityEv
 __ZN3WTF37scheduleDispatchFunctionsOnMainThreadEv
 __ZN3WTF15ThreadCondition4waitERNS_5MutexE
 __ZN3WTF16callOnMainThreadEPFvPvES0_
 __ZN3WTF5DequeINS_19FunctionWithContextEE14expandCapacityEv
 __ZN3WTF37scheduleDispatchFunctionsOnMainThreadEv
 __ZN3WTF15ThreadCondition4waitERNS_5MutexE
-__ZN3JSC8DebuggerC2Ev
+__ZN3WTF17TCMalloc_PageHeap3NewEm
+__ZN7WebCore12AtomicString4initEv
+__ZN3WTF7HashSetIPN7WebCore10StringImplENS1_10StringHashENS_10HashTraitsIS3_EEE3addIPKcNS1_17CStringTranslatorEEESt4pairINS_24H
+__ZN3WTF9HashTableIPN7WebCore10StringImplES3_NS_17IdentityExtractorIS3_EENS1_10StringHashENS_10HashTraitsIS3_EES8_E6rehashEi
+__ZN7WebCore12AtomicString3addEPKc
+__ZN7WebCore12AtomicString3addEPNS_10StringImplE
+__ZN7WebCore6StringC1EPKcj
+__ZN7WebCore5equalEPKNS_10StringImplEPKc
+__ZNK7WebCore6String6lengthEv
+__ZNK7WebCore6StringixEj
+__ZNK7WebCore6String9substringEjj
+__ZN7WebCore10StringImpl9substringEjj
+__ZNK7WebCore6String5lowerEv
+__ZN7WebCore10StringImpl5lowerEv
+__ZN7WebCore10StringImpl4findEti
+__ZNK7WebCore6String10charactersEv
+__ZN7WebCore17equalIgnoringCaseEPNS_10StringImplES1_
+__ZN7WebCore17equalIgnoringCaseEPNS_10StringImplEPKc
+__ZN7WebCore12AtomicString3addEPKtj
+__ZN3WTF7HashSetIPN7WebCore10StringImplENS1_10StringHashENS_10HashTraitsIS3_EEE3addINS1_11UCharBufferENS1_21UCharBufferTranslat
+__ZN7WebCore18charactersToDoubleEPKtmPb
 __ZN3WTF6strtodEPKcPPc
 __ZN3WTF6strtodEPKcPPc
-__ZN3WTF15ThreadCondition6signalEv
-__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd
 __ZN3WTF15ThreadCondition9broadcastEv
 __ZN3WTF15ThreadCondition9broadcastEv
--[WTFMainThreadCaller call]
-__ZN3WTF31dispatchFunctionsFromMainThreadEv
-__ZN3WTF14FastMallocZone9forceLockEP14_malloc_zone_t
-__ZN3WTF11fastReallocEPvm
-__ZN3WTF11fastReallocILb1EEEPvS1_m
-__ZN3JSC7UStringC1EPKti
-__ZN3JSC7UStringC2EPKti
-__ZN3JSC12JSGlobalData12createLeakedEv
+__ZN3WTF15ThreadCondition6signalEv
+__ZN7WebCore12AtomicString6removeEPNS_10StringImplE
+__ZN3JSC12JSGlobalData12createLeakedENS_15ThreadStackTypeE
 __ZN3JSC9Structure18startIgnoringLeaksEv
 __ZN3JSC9Structure18startIgnoringLeaksEv
-__ZN3JSC7VPtrSetC2Ev
-__ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoE
-__ZN3JSC7JSArrayC1EN3WTF10PassRefPtrINS_9StructureEEE
-__ZN3JSC7JSArrayD1Ev
-__ZN3JSC7JSArrayD2Ev
-__ZN3WTF10RefCountedIN3JSC9StructureEE5derefEv
-__ZN3JSC9StructureD1Ev
-__ZN3JSC9StructureD2Ev
-__ZN3JSC11JSByteArray15createStructureENS_7JSValueE
-__ZN3JSC11JSByteArrayD1Ev
-__ZN3JSC8JSStringD1Ev
-__ZN3JSC10JSFunctionD1Ev
-__ZN3JSC10JSFunctionD2Ev
-__ZN3JSC8JSObjectD2Ev
-__ZN3JSC12JSGlobalDataC2EbRKNS_7VPtrSetE
-__ZN3JSC21createIdentifierTableEv
+__ZN3JSC12JSGlobalDataC2ENS0_14GlobalDataTypeENS_15ThreadStackTypeE
 __ZN3JSC17CommonIdentifiersC1EPNS_12JSGlobalDataE
 __ZN3JSC17CommonIdentifiersC2EPNS_12JSGlobalDataE
 __ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKc
 __ZN3JSC17CommonIdentifiersC1EPNS_12JSGlobalDataE
 __ZN3JSC17CommonIdentifiersC2EPNS_12JSGlobalDataE
 __ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKc
-__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addIPKcNS1_17CStringTranslatorEEESt4pairINS_24HashT
-__ZN3WTF9HashTableIPN3JSC7UString3RepES4_NS_17IdentityExtractorIS4_EENS_7StrHashIS4_EENS_10HashTraitsIS4_EESA_E6rehashEi
-__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN3JSC7UString3RepEEEENS_18PairFirstExtractorIS9_EENS_7PtrHashIS2_EENS_14PairHashTra
-__ZN3WTF6RefPtrIN3JSC7UString3RepEED1Ev
+__ZN3WTF7HashSetIPN7WebCore10StringImplENS1_10StringHashENS_10HashTraitsIS3_EEE3addIPKcN3JSC27IdentifierCStringTranslatorEEESt4
+__ZN3WTF9HashTableIPN7WebCore10StringImplES3_NS_17IdentityExtractorIS3_EENS1_10StringHashENS_10HashTraitsIS3_EES8_E6expandEv
+__ZN3WTF9HashTableIPKcSt4pairIS2_NS_6RefPtrIN7WebCore10StringImplEEEENS_18PairFirstExtractorIS8_EENS_7PtrHashIS2_EENS_14PairHas
+__ZN3JSC10IdentifierC1EPNS_12JSGlobalDataEPKc
 __ZN3JSC12SmallStringsC1Ev
 __ZN3JSC19ExecutableAllocator17intializePageSizeEv
 __ZN3JSC14ExecutablePool11systemAllocEm
 __ZN3JSC5LexerC1EPNS_12JSGlobalDataE
 __ZN3JSC12SmallStringsC1Ev
 __ZN3JSC19ExecutableAllocator17intializePageSizeEv
 __ZN3JSC14ExecutablePool11systemAllocEm
 __ZN3JSC5LexerC1EPNS_12JSGlobalDataE
-__ZN3JSC5LexerC2EPNS_12JSGlobalDataE
+__ZN3JSC11ParserArenaC1Ev
+__ZN3JSC11ParserArenaC2Ev
 __ZN3JSC11InterpreterC1Ev
 __ZN3JSC11InterpreterC2Ev
 __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
+__ZN3JSC9JITThunksC1EPNS_12JSGlobalDataE
 __ZN3JSC3JITC1EPNS_12JSGlobalDataEPNS_9CodeBlockE
 __ZN3JSC3JITC2EPNS_12JSGlobalDataEPNS_9CodeBlockE
 __ZN3JSC3JITC1EPNS_12JSGlobalDataEPNS_9CodeBlockE
 __ZN3JSC3JITC2EPNS_12JSGlobalDataEPNS_9CodeBlockE
-__ZN3JSC3JIT35privateCompileCTIMachineTrampolinesEPN3WTF6RefPtrINS_14ExecutablePoolEEEPNS_12JSGlobalDataEPPvS9_S9_S9_S9_S9_
-__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDE
+__ZN3JSC3JIT35privateCompileCTIMachineTrampolinesEPN3WTF6RefPtrINS_14ExecutablePoolEEEPNS_12JSGlobalDataEPNS_19TrampolineStruct
+__ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common9ConditionENS_12X86Registers10RegisterIDES4_
+__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDE
 __ZN3JSC12X86Assembler3jCCENS0_9ConditionE
 __ZN3JSC12X86Assembler3jCCENS0_9ConditionE
-__ZN3JSC23MacroAssemblerX86Common4moveENS_22AbstractMacroAssemblerINS_12X86AssemblerEE6ImmPtrENS_3X8610RegisterIDE
-__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDEi
-__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDE
+__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_12X86Registers10RegisterIDEi
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDE
 __ZN3JSC15AssemblerBuffer11ensureSpaceEi
 __ZN3JSC15AssemblerBuffer11ensureSpaceEi
-__ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common9ConditionENS_3X8610RegisterIDENS_22AbstractMacroAsse
-__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDENS_3X8610RegisterIDE
 __ZN3JSC20MacroAssemblerX86_644callEv
 __ZN3JSC20MacroAssemblerX86_644callEv
-__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDEi
+__ZN3JSC20MacroAssemblerX86_647loadPtrENS_22AbstractMacroAssemblerINS_12X86AssemblerEE15ImplicitAddressENS_12X86Registers10Regi
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDENS_12X86Registers10RegisterIDE
 __ZN3JSC3JIT32compileOpCallInitializeCallFrameEv
 __ZN3JSC3JIT32compileOpCallInitializeCallFrameEv
-__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_3X8610RegisterIDEi
-__ZN3JSC20MacroAssemblerX86_6421makeTailRecursiveCallENS_22AbstractMacroAssemblerINS_12X86AssemblerEE4JumpE
+__ZN3JSC15AssemblerBuffer4growEi
+__ZN3WTF11fastReallocEPvm
+__ZN3WTF11fastReallocILb1EEEPvS1_m
+__ZN3WTF10RefCountedIN3JSC14ExecutablePoolEE5derefEv
 __ZN3JSC14TimeoutCheckerC1Ev
 __ZN3JSC4HeapC1EPNS_12JSGlobalDataE
 __ZN3JSC14TimeoutCheckerC1Ev
 __ZN3JSC4HeapC1EPNS_12JSGlobalDataE
+__ZN3JSC4Heap13allocateBlockEv
+__ZN3JSC9MarkStack18initializePagesizeEv
+__ZN3JSC9MarkStack13allocateStackEm
 __ZN3JSC27startProfilerServerIfNeededEv
 +[ProfilerServer sharedProfileServer]
 -[ProfilerServer init]
 __ZN3JSC9Structure17stopIgnoringLeaksEv
 __ZN3JSC27startProfilerServerIfNeededEv
 +[ProfilerServer sharedProfileServer]
 -[ProfilerServer init]
 __ZN3JSC9Structure17stopIgnoringLeaksEv
+__ZNK7WebCore6String6latin1Ev
+__ZNK3WTF7CString6lengthEv
+__ZN7WebCore10StringImpl22containsOnlyWhitespaceEv
+__ZN7WebCore12AtomicString3addEPKt
+__ZN7WebCore10StringImpl11reverseFindEPS0_ib
+__ZN7WebCore10StringImpl5adoptERNS_12StringBufferE
+__ZNK7WebCore6String5splitEtRN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5splitERKS0_bRN3WTF6VectorIS0_Lm0EEE
+-[WTFMainThreadCaller call]
+__ZN3WTF31dispatchFunctionsFromMainThreadEv
+__ZN3WTF15ThreadCondition9timedWaitERNS_5MutexEd
+__ZN3WTF14FastMallocZone9forceLockEP14_malloc_zone_t
+__ZN3WTF14FastMallocZone11forceUnlockEP14_malloc_zone_t
+__ZN3WTF20TCMalloc_ThreadCache18DestroyThreadCacheEPv
+__ZN3WTF20TCMalloc_ThreadCache11DeleteCacheEPS0_
+__ZN3WTF25TCMalloc_Central_FreeList11InsertRangeEPvS1_i
+__ZN3WTF25TCMalloc_Central_FreeList18ReleaseListToSpansEPv
+__ZN3WTF20ThreadIdentifierData8destructEPv
+__ZN3WTF31clearPthreadHandleForIdentifierEj
+__ZN3WTF12detachThreadEj
+__ZN3WTFL26pthreadHandleForIdentifierEj
+__ZN7WebCore6StringC1EPKtj
+__Z15jsRegExpCompilePKti24JSRegExpIgnoreCaseOption23JSRegExpMultilineOptionPjPPKc
+__ZL30calculateCompiledPatternLengthPKti24JSRegExpIgnoreCaseOptionR11CompileDataR9ErrorCode
+__ZL11checkEscapePPKtS0_P9ErrorCodeib
+__ZL13compileBranchiPiPPhPPKtS3_P9ErrorCodeS_S_R11CompileData
+__Z15jsRegExpExecutePK8JSRegExpPKtiiPii
+__ZL5matchPKtPKhiR9MatchData
+__ZN7WebCore6String6formatEPKcz
+__ZNK7WebCore6String19characterStartingAtEj
+__ZN7WebCore10StringImpl19characterStartingAtEj
+__ZN3WTF25TCMalloc_Central_FreeList11ShrinkCacheEib
+__ZNK7WebCore6String16removeCharactersEPFbtE
+__ZN7WebCore10StringImpl16removeCharactersEPFbtE
+__ZN7WebCore10StringImpl7replaceEtt
+__ZNK7WebCore6String4utf8Ev
+__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
+__ZN3WTF7CStringC1EPKcj
+__ZN3WTF7CString4initEPKcj
+__ZN7WebCore10StringImpl4findEPFbtEi
 __ZN3JSC4Heap8allocateEm
 __ZN3JSC4Heap8allocateEm
-__ZN3JSCL13allocateBlockILNS_8HeapTypeE0EEEPNS_14CollectorBlockEv
-__ZN3JSC4Heap4heapENS_7JSValueE
+__ZN3JSC6JSCellD1Ev
 __ZN3JSC4Heap7protectENS_7JSValueE
 __ZN3JSC4Heap7protectENS_7JSValueE
-__ZN3WTF7HashMapIPN3JSC6JSCellEjNS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS6_IjEEE3addERKS3_RKj
 __ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraits
 __ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
 __ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
 __ZN3JSC14JSGlobalObject5resetENS_7JSValueE
 __ZN3WTF9HashTableIPN3JSC6JSCellESt4pairIS3_jENS_18PairFirstExtractorIS5_EENS_7PtrHashIS3_EENS_14PairHashTraitsINS_10HashTraits
 __ZN3JSC14JSGlobalObjectnwEmPNS_12JSGlobalDataE
 __ZN3JSC14JSGlobalObject4initEPNS_8JSObjectE
 __ZN3JSC14JSGlobalObject5resetENS_7JSValueE
-__ZN3JSC4Heap12heapAllocateILNS_8HeapTypeE0EEEPvm
-__ZN3JSC8jsStringEPNS_12JSGlobalDataERKNS_7UStringE
-__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
+__ZN3JSC17FunctionPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC17FunctionPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC16InternalFunctionC2EPNS_12JSGlobalDataEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_10IdentifierE
 __ZN3JSC7UStringC1EPKc
 __ZN3JSC7UStringC1EPKc
-__ZN3JSCL9createRepEPKc
-__ZN3JSC8JSObject9putDirectERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotE
-__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjRm
-__ZN3JSC9Structure3getERKNS_10IdentifierERj
-__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjRm
-__ZN3JSC9Structure3putERKNS_10IdentifierEj
-__ZN3JSC8JSObject26putDirectWithoutTransitionERKNS_10IdentifierENS_7JSValueEj
-__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEj
+__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
+__ZN3JSC8JSObject17putDirectInternalERKNS_10IdentifierENS_7JSValueEjbRNS_15PutPropertySlotEPNS_6JSCellE
+__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
+__ZN3JSC9Structure3getEPKN7WebCore10StringImplERjRPNS_6JSCellE
+__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
+__ZN3JSC9Structure3putERKNS_10IdentifierEjPNS_6JSCellE
+__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEjPNS_6JSCellE
 __ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_9StructureEPPNS_10JSFunctionES7_
 __ZN3JSC17FunctionPrototype21addFunctionPropertiesEPNS_9ExecStateEPNS_9StructureEPPNS_10JSFunctionES7_
-__ZN3JSC10JSFunctionC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RK
-__ZN3JSC12JSGlobalData17createNativeThunkEv
-__ZN3JSC16FunctionBodyNode17createNativeThunkEPNS_12JSGlobalDataE
-__ZN3WTF6VectorINS_6RefPtrIN3JSC21ParserArenaRefCountedEEELm0EE15reserveCapacityEm
-__ZN3JSC11ParserArena5resetEv
+__ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjec
+__ZN3JSC10JSFunctionC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjec
 __ZN3JSC8JSObject34putDirectFunctionWithoutTransitionEPNS_9ExecStateEPNS_16InternalFunctionEj
 __ZN3JSC8JSObject34putDirectFunctionWithoutTransitionEPNS_9ExecStateEPNS_16InternalFunctionEj
-__ZN3JSC15ObjectPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC16InternalFunction4nameEPNS_9ExecStateE
+__ZN3JSC15ObjectPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC15ObjectPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
 __ZN3JSC9Structure26rehashPropertyMapHashTableEj
 __ZN3JSC9Structure26rehashPropertyMapHashTableEj
-__ZN3JSC15StringPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
-__ZN3JSC16BooleanPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC15NumberPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC15RegExpPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC14ErrorPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_
-__ZN3JSC20NativeErrorPrototypeC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringES9_
-__ZN3JSC17ObjectConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_15ObjectPrototypeE
-__ZN3JSC19FunctionConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_17FunctionPrototypeE
+__ZN3JSC8JSObject17createInheritorIDEv
+__ZN3JSC14ArrayPrototypeC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC7JSArrayC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC15StringPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC15StringPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC16BooleanPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC16BooleanPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC13BooleanObjectC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC15NumberPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC15NumberPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC12NumberObjectC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC13DatePrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC12DateInstanceC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC15RegExpPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC15RegExpPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC14ErrorPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC14ErrorPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_
+__ZN3JSC13ErrorInstanceC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC20NativeErrorPrototypeC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7UStringES9_
+__ZN3JSC20NativeErrorPrototypeC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7UStringES9_
+__ZN3JSC17ObjectConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15ObjectPrototypeEPS5_
+__ZN3JSC17ObjectConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15ObjectPrototypeEPS5_
+__ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
+__ZN3JSC19FunctionConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_17FunctionPrototypeE
+__ZN3JSC19FunctionConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_17FunctionPrototypeE
 __ZNK3JSC16InternalFunction9classInfoEv
 __ZNK3JSC16InternalFunction9classInfoEv
-__ZN3JSC16ArrayConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_14ArrayPrototypeE
+__ZN3JSC16ArrayConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_14ArrayPrototypeEPS5_
+__ZN3JSC16ArrayConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_14ArrayPrototypeEPS5_
 __ZNK3JSC14ArrayPrototype9classInfoEv
 __ZNK3JSC14ArrayPrototype9classInfoEv
-__ZN3JSC17StringConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_PNS_15StringPrototypeE
+__ZN3JSC17StringConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_PNS_15StringPrototypeE
+__ZN3JSC17StringConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_PNS_15StringPrototypeE
 __ZNK3JSC15StringPrototype9classInfoEv
 __ZNK3JSC15StringPrototype9classInfoEv
-__ZN3JSC18BooleanConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_16BooleanPrototypeE
+__ZN3JSC9JITThunks16specializedThunkEPNS_12JSGlobalDataEPFN3WTF10PassRefPtrINS_16NativeExecutableEEES2_PNS_14ExecutablePoolEE
+__ZN3JSC26fromCharCodeThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpList6appendENS2_4JumpE
+__ZN3JSCL12charToStringERNS_19SpecializedThunkJITEPNS_12JSGlobalDataENS_12X86Registers10RegisterIDES5_S5_
+__ZN3JSC19SpecializedThunkJIT8finalizeEv
+__ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPNS_16NativeExecutableEPFNS_7
+__ZN3JSC10JSFunctionC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPNS_16NativeExecutableEPFNS_7
+__ZN3JSC8JSObject23allocatePropertyStorageEmm
+__ZN3JSC18BooleanConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_16BooleanPrototypeE
+__ZN3JSC18BooleanConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_16BooleanPrototypeE
 __ZNK3JSC13BooleanObject9classInfoEv
 __ZNK3JSC13BooleanObject9classInfoEv
-__ZN3JSC17NumberConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_15NumberPrototypeE
-__ZN3JSC15DateConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPS5_PNS_13DatePrototypeE
+__ZN3JSC17NumberConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15NumberPrototypeE
+__ZN3JSC17NumberConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15NumberPrototypeE
+__ZN3JSC15DateConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_PNS_13DatePrototypeE
+__ZN3JSC15DateConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPS5_PNS_13DatePrototypeE
 __ZNK3JSC13DatePrototype9classInfoEv
 __ZNK3JSC13DatePrototype9classInfoEv
-__ZN3JSC17RegExpConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_15RegExpPrototypeE
-__ZN3JSC16ErrorConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_14ErrorPrototypeE
+__ZN3JSC17RegExpConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15RegExpPrototypeE
+__ZN3JSC17RegExpConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_15RegExpPrototypeE
+__ZN3JSC16ErrorConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_14ErrorPrototypeE
+__ZN3JSC16ErrorConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_14ErrorPrototypeE
 __ZNK3JSC13ErrorInstance9classInfoEv
 __ZNK3JSC13ErrorInstance9classInfoEv
-__ZN3JSC22NativeErrorConstructorC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS_20NativeErrorPrototypeE
-__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPNS_7UString3RepE
-__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addERKS4_
-__ZN3JSC10MathObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEE
+__ZN3JSC22NativeErrorConstructorC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_20NativeErrorPrototypeE
+__ZN3JSC22NativeErrorConstructorC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_20NativeErrorPrototypeE
+__ZNK3JSC6JSCell9getStringEPNS_9ExecStateE
+__ZN3JSC10Identifier11addSlowCaseEPNS_9ExecStateEPN7WebCore10StringImplE
+__ZN3WTF7HashSetIPN7WebCore10StringImplENS1_10StringHashENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3JSC10MathObjectC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC10MathObjectC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
 __ZN3JSC12SmallStrings24singleCharacterStringRepEh
 __ZN3JSC12SmallStrings24singleCharacterStringRepEh
-__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEENS2_16SymbolTableEntryENS2_17IdentifierRepHashENS_10HashTraitsIS5_EENS2_26Symbo
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_NS2_16SymbolTableEntryEENS_18PairFirstExtractorIS8_EENS2_17Identif
-__ZN3JSC17PrototypeFunctionC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjec
+__ZN3JSC19SmallStringsStorageC2Ev
+__ZN3JSC18GlobalEvalFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_
+__ZN3JSC17PrototypeFunctionC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8
 __ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE
 __ZN3JSC9Structure17copyPropertyTableEv
 __ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE
 __ZN3JSC9Structure17copyPropertyTableEv
+__ZN3WTF10RefCountedIN3JSC9StructureEE5derefEv
 __ZN3JSC14JSGlobalObject10globalExecEv
 __ZN3JSC14JSGlobalObject10globalExecEv
-__ZN3JSC10Identifier3addEPNS_9ExecStateEPKc
 __ZN3JSC4Heap9unprotectENS_7JSValueE
 __ZN3JSC4Heap9unprotectENS_7JSValueE
-__ZN3JSC6JSCellnwEmPNS_9ExecStateE
 __ZN3JSC14TimeoutChecker5resetEv
 __ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_7JSValueE
 __ZN3JSC14TimeoutChecker5resetEv
 __ZN3JSC8evaluateEPNS_9ExecStateERNS_10ScopeChainERKNS_10SourceCodeENS_7JSValueE
-__ZN3JSC6JSLock4lockEb
-__ZN3JSC6Parser5parseINS_11ProgramNodeEEEN3WTF10PassRefPtrIT_EEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
+__ZN3JSC6JSLockC1EPNS_9ExecStateE
+__ZN3JSC6JSLock4lockENS_14JSLockBehaviorE
+__ZN3JSC17ProgramExecutable7compileEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3JSC6Parser5parseINS_11ProgramNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCod
 __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
 __ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
-__ZN3JSC7UStringaSEPKc
+__ZN3JSC5Lexer7setCodeERKNS_10SourceCodeERNS_11ParserArenaE
 __Z10jscyyparsePv
 __ZN3JSC5Lexer3lexEPvS1_
 __ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKti
 __Z10jscyyparsePv
 __ZN3JSC5Lexer3lexEPvS1_
 __ZN3JSC10Identifier3addEPNS_12JSGlobalDataEPKti
-__ZN3WTF7HashSetIPN3JSC7UString3RepENS_7StrHashIS4_EENS_10HashTraitsIS4_EEE3addINS1_11UCharBufferENS1_21UCharBufferTranslatorEE
-__ZN3WTF15SegmentedVectorINS_10IdentifierELm64EE6appendIS1_EEvRKT_
+__ZN3WTF7HashSetIPN7WebCore10StringImplENS1_10StringHashENS_10HashTraitsIS3_EEE3addIN3JSC11UCharBufferENS9_31IdentifierUCharBuf
 __ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
 __ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
-__ZN3JSC20ParserArenaDeletablenwEmPNS_12JSGlobalDataE
-__ZN3WTF6VectorIPN3JSC20ParserArenaDeletableELm0EE15reserveCapacityEm
-__ZN3JSC5Lexer10sourceCodeEiii
-__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeE
-__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm
-__ZN3WTF6VectorIPN3JSC12FuncDeclNodeELm0EE14expandCapacityEm
+__ZN3JSC11ParserArena20allocateFreeablePoolEv
+__ZL20makeFunctionCallNodePN3JSC12JSGlobalDataENS_8NodeInfoIPNS_14ExpressionNodeEEENS2_IPNS_13ArgumentsNodeEEEiii
+__ZNK3JSC15DotAccessorNode10isLocationEv
+__ZNK3JSC14ExpressionNode13isResolveNodeEv
+__ZNK3JSC14ExpressionNode21isBracketAccessorNodeEv
+__ZL14makeAssignNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeENS_8OperatorES3_bbiii
+__ZNK3JSC11ResolveNode10isLocationEv
+__ZNK3JSC11ResolveNode13isResolveNodeEv
+__ZN3JSC13StatementNode6setLocEii
+__ZN3WTF6VectorIPN3JSC20ParserArenaDeletableELm0EE14expandCapacityEm
 __ZN3JSC14SourceElements6appendEPNS_13StatementNodeE
 __ZNK3JSC13StatementNode16isEmptyStatementEv
 __ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEm
 __ZN3JSC14SourceElements6appendEPNS_13StatementNodeE
 __ZNK3JSC13StatementNode16isEmptyStatementEv
 __ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14expandCapacityEm
-__ZL20makeFunctionCallNodePvN3JSC8NodeInfoIPNS0_14ExpressionNodeEEENS1_IPNS0_13ArgumentsNodeEEEiii
-__ZNK3JSC11ResolveNode10isLocationEv
-__ZNK3JSC11ResolveNode13isResolveNodeEv
-__ZN3JSC5Lexer7record8Ei
-__ZN3JSC5Lexer10scanRegExpEv
-__ZN3JSC7UStringC2ERKN3WTF6VectorItLm0EEE
-__ZN3JSC7UString3Rep7destroyEv
+__ZN3JSC6Parser16didFinishParsingEPNS_14SourceElementsEPNS_15ParserArenaDataIN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEEEP
 __ZN3JSC5Lexer5clearEv
 __ZN3JSC5Lexer5clearEv
-__ZN3JSC10Identifier6removeEPNS_7UString3RepE
-__ZN3WTF6VectorIN3JSC10IdentifierELm64EE14shrinkCapacityEm
-__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairINS_10IdentifierEjELm0EEEPN
-__ZN3WTF6VectorIPN3JSC13StatementNodeELm0EE14shrinkCapacityEm
+__ZN3JSC11ProgramNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_
+__ZN3JSC9ScopeNodeC2EPNS_12JSGlobalDataERKNS_10SourceCodeEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEE
+__ZN3JSC11ParserArena14derefWithArenaEN3WTF10PassRefPtrINS_21ParserArenaRefCountedEEE
 __ZN3JSC11ParserArena10removeLastEv
 __ZN3JSC11ParserArena10removeLastEv
-__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
-__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_7UString3RepEEEN
-__ZN3WTF6VectorIN3JSC11InstructionELm0EE14expandCapacityEm
-__ZN3JSC9Structure22toDictionaryTransitionEPS0_
-__ZN3JSC8JSObject12removeDirectERKNS_10IdentifierE
-__ZN3JSC9Structure31removePropertyWithoutTransitionERKNS_10IdentifierE
-__ZN3JSC9Structure6removeERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_12FuncDeclNodeE
-__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv
-__ZN3JSC17BytecodeGenerator11newRegisterEv
-__ZN3JSC9Structure24fromDictionaryTransitionEPS0_
+__ZN3JSC11ParserArena5resetEv
+__ZN3WTF6VectorIN3JSC10IdentifierELm64EE14shrinkCapacityEm
+__ZN3JSC9CodeBlockC2EPNS_16ScriptExecutableENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourceProviderEEEjPNS4_7HashMapINS4_6RefPtrIN7W
+__ZN3WTF7HashSetIPN3JSC15GlobalCodeBlockENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC15GlobalCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3JSC17BytecodeGeneratorC1EPNS_11ProgramNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrIN7WebCore10StringIm
+__ZN3JSC17BytecodeGeneratorC2EPNS_11ProgramNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrIN7WebCore10StringIm
+__ZN3WTF6VectorIN3JSC11InstructionELm0EE15reserveCapacityEm
+__ZN3JSC9Structure31toCacheableDictionaryTransitionEPS0_
+__ZN3JSC9Structure22toDictionaryTransitionEPS0_NS0_14DictionaryKindE
+__ZN3JSC9Structure26flattenDictionaryStructureEPNS_8JSObjectE
 __ZN3JSC17BytecodeGenerator8generateEv
 __ZN3JSC11ProgramNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator13emitDebugHookENS_11DebugHookIDEii
 __ZN3JSC17BytecodeGenerator8generateEv
 __ZN3JSC11ProgramNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator13emitDebugHookENS_11DebugHookIDEii
-__ZN3JSC17BytecodeGenerator11addConstantENS_7JSValueE
-__ZN3WTF9HashTableIPvSt4pairIS1_jENS_18PairFirstExtractorIS3_EENS_7PtrHashIS1_EENS_14PairHashTraitsIN3JSC17JSValueHashTraitsENS
-__ZN3WTF6VectorIN3JSC8RegisterELm0EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_
-__ZN3JSC17BytecodeGenerator8emitNodeEPNS_10RegisterIDEPNS_4NodeE
+__ZN3JSC17BytecodeGenerator12newTemporaryEv
+__ZN3JSC17BytecodeGenerator11newRegisterEv
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDENS_7JSValueE
+__ZN3JSC17BytecodeGenerator16addConstantValueENS_7JSValueE
+__ZN3WTF9HashTableIPvSt4pairIS1_jENS_18PairFirstExtractorIS3_EENS_7PtrHashIS1_EENS_14PairHashTraitsIN3JSC24EncodedJSValueHashTr
+__ZN3WTF6VectorIN3JSC8RegisterELm0EE15reserveCapacityEm
 __ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm
 __ZN3WTF6VectorIN3JSC8LineInfoELm0EE14expandCapacityEm
-__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17ExprStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17AssignResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE
 __ZN3JSC17BytecodeGenerator11registerForERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_S3_PNS_13ArgumentsNodeEjjj
-__ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
-__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm
-__ZN3WTF6VectorIN3JSC12CallLinkInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRbRPNS_8JSObjectE
+__ZN3JSC17BytecodeGenerator15emitResolveBaseEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3JSC19FunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11NewExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC11ResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3WTF6VectorIN3JSC17GlobalResolveInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE
+__ZN3WTF9HashTableINS_6RefPtrIN7WebCore10StringImplEEESt4pairIS4_iENS_18PairFirstExtractorIS6_EEN3JSC17IdentifierRepHashENS_14P
+__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEmPKS2_
+__ZN3WTF6VectorIN3JSC10IdentifierELm0EE15reserveCapacityEm
+__ZN3JSC17BytecodeGenerator13emitConstructEPNS_10RegisterIDES2_PNS_13ArgumentsNodeEjjj
+__ZN3WTF6VectorIN3JSC20GetByIdExceptionInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC12CallLinkInfoELm0EE15reserveCapacityEm
+__ZN3JSC17BytecodeGenerator15emitMethodCheckEv
+__ZN3JSC17BytecodeGenerator8emitCallEPNS_10RegisterIDES2_S2_PNS_13ArgumentsNodeEjjj
+__ZN3JSC17BytecodeGenerator8emitCallENS_8OpcodeIDEPNS_10RegisterIDES3_S3_PNS_13ArgumentsNodeEjjj
+__ZN3JSC17BytecodeGenerator11emitPutByIdEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC17BytecodeGenerator16emitUnaryNoDstOpENS_8OpcodeIDEPNS_10RegisterIDE
 __ZN3JSC12JSGlobalData22numericCompareFunctionEPNS_9ExecStateE
 __ZNK3JSC21UStringSourceProvider6lengthEv
 __ZN3JSC12JSGlobalData22numericCompareFunctionEPNS_9ExecStateE
 __ZNK3JSC21UStringSourceProvider6lengthEv
+__ZN3JSC18FunctionExecutable14fromGlobalCodeERKNS_10IdentifierEPNS_9ExecStateEPNS_8DebuggerERKNS_10SourceCodeEPiPNS_7UStringE
 __ZNK3JSC21UStringSourceProvider4dataEv
 __ZNK3JSC21UStringSourceProvider4dataEv
-__ZN3JSC19extractFunctionBodyEPNS_11ProgramNodeE
+__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataE
+__ZN3JSC5Lexer10sourceCodeEiii
+__ZN3JSC16FunctionBodyNode13finishParsingERKNS_10SourceCodeEPNS_13ParameterNodeERKNS_10IdentifierE
+__ZN3WTF6VectorIN3JSC10IdentifierELm0EE14expandCapacityEm
+__ZN3JSC16FunctionBodyNode13finishParsingEN3WTF10PassRefPtrINS_18FunctionParametersEEERKNS_10IdentifierE
+__ZNK3JSC9ScopeNode15singleStatementEv
 __ZNK3JSC17ExprStatementNode15isExprStatementEv
 __ZNK3JSC12FuncExprNode14isFuncExprNodeEv
 __ZNK3JSC17ExprStatementNode15isExprStatementEv
 __ZNK3JSC12FuncExprNode14isFuncExprNodeEv
-__ZN3JSC16FunctionBodyNode16generateBytecodeEPNS_14ScopeChainNodeE
-__ZN3JSC6Parser14reparseInPlaceEPNS_12JSGlobalDataEPNS_16FunctionBodyNodeE
-__ZL11makeSubNodePvPN3JSC14ExpressionNodeES2_b
+__ZThn16_N3JSC11ProgramNodeD0Ev
+__ZN3JSC11ProgramNodeD0Ev
+__ZN3JSC11ParserArenaD1Ev
+__ZN3JSC14SourceElementsD1Ev
+__ZThn16_N3JSC16FunctionBodyNodeD0Ev
+__ZN3JSC16FunctionBodyNodeD0Ev
+__ZN3JSC18FunctionExecutable7compileEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3JSC6Parser5parseINS_16FunctionBodyNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPNS_8DebuggerEPNS_9ExecStateERKNS_10Sour
+__ZL11makeSubNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
 __ZN3JSC14ExpressionNode14stripUnaryPlusEv
 __ZNK3JSC14ExpressionNode8isNumberEv
 __ZN3JSC14ExpressionNode14stripUnaryPlusEv
 __ZNK3JSC14ExpressionNode8isNumberEv
-__ZN3JSC9CodeBlockC1EPNS_9ScopeNodeENS_8CodeTypeEN3WTF10PassRefPtrINS_14SourceProviderEEEj
-__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrINS_7UString3Re
+__ZN3JSC16FunctionBodyNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_
+__ZN3JSC17BytecodeGeneratorC1EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrIN7WebCore10Str
+__ZN3JSC17BytecodeGeneratorC2EPNS_16FunctionBodyNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrIN7WebCore10Str
 __ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierE
 __ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE
 __ZN3JSC17BytecodeGenerator12addParameterERKNS_10IdentifierE
 __ZN3JSC16FunctionBodyNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC9BlockNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC10ReturnNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC12BinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZNK3JSC11ResolveNode6isPureERNS_17BytecodeGeneratorE
-__ZN3JSC17BytecodeGenerator12newTemporaryEv
+__ZN3JSC17BytecodeGenerator7isLocalERKNS_10IdentifierE
 __ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE
 __ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE
 __ZNK3JSC9BlockNode7isBlockEv
 __ZNK3JSC10ReturnNode12isReturnNodeEv
 __ZN3JSC9CodeBlock11shrinkToFitEv
 __ZN3WTF6VectorIN3JSC11InstructionELm0EE14shrinkCapacityEm
 __ZN3JSC17BytecodeGenerator12emitBinaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_NS_12OperandTypesE
 __ZN3JSC17BytecodeGenerator10emitReturnEPNS_10RegisterIDE
 __ZNK3JSC9BlockNode7isBlockEv
 __ZNK3JSC10ReturnNode12isReturnNodeEv
 __ZN3JSC9CodeBlock11shrinkToFitEv
 __ZN3WTF6VectorIN3JSC11InstructionELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIN3JSC10IdentifierELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE14shrinkCapacityEm
 __ZN3WTF6VectorIN3JSC10IdentifierELm0EE14shrinkCapacityEm
-__ZN3JSC11ParserArenaD1Ev
-__ZN3JSC11ResolveNodeD0Ev
-__ZN3JSC7SubNodeD0Ev
-__ZN3JSC10ReturnNodeD0Ev
-__ZN3JSC14SourceElementsD0Ev
-__ZN3JSC9BlockNodeD0Ev
 __ZN3JSC17BytecodeGeneratorD2Ev
 __ZN3WTF6VectorIN3JSC11InstructionELm0EEaSERKS3_
 __ZN3JSC17BytecodeGeneratorD2Ev
 __ZN3WTF6VectorIN3JSC11InstructionELm0EEaSERKS3_
-__ZThn16_N3JSC11ProgramNodeD0Ev
-__ZN3JSC11ProgramNodeD0Ev
-__ZN3JSC13ParameterNodeD0Ev
-__ZN3JSC17ExprStatementNodeD0Ev
-__ZThn16_N3JSC12FuncExprNodeD0Ev
-__ZN3JSC12FuncExprNodeD0Ev
-__ZThn16_N3JSC16FunctionBodyNodeD0Ev
-__ZN3JSC16FunctionBodyNodeD0Ev
-__ZN3JSC9CodeBlockD1Ev
+__ZN3JSC18FunctionExecutableD0Ev
+__ZN3JSC17FunctionCodeBlockD0Ev
 __ZN3JSC9CodeBlockD2Ev
 __ZN3JSC21UStringSourceProviderD0Ev
 __ZN3JSC9CodeBlockD2Ev
 __ZN3JSC21UStringSourceProviderD0Ev
-__ZN3WTF6VectorIN3JSC19ExpressionRangeInfoELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIN3JSC8LineInfoELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorINS_6RefPtrIN3JSC12FuncDeclNodeEEELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm
-__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm
-__ZN3JSC15ParserArenaDataIN3WTF6VectorIPNS_12FuncDeclNodeELm0EEEED0Ev
-__ZN3JSC16ArgumentListNodeD0Ev
-__ZN3JSC13ArgumentsNodeD0Ev
-__ZN3JSC23FunctionCallResolveNodeD0Ev
+__ZNK3JSC8JSObject8toObjectEPNS_9ExecStateE
+__ZN3JSC11Interpreter7executeEPNS_17ProgramExecutableEPNS_9ExecStateEPNS_14ScopeChainNodeEPNS_8JSObjectEPNS_7JSValueE
+__ZN3JSC12JSGlobalData14resetDateCacheEv
+__ZN3JSC12RegisterFile12globalObjectEv
 __ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE
 __ZN3JSC14JSGlobalObject13copyGlobalsToERNS_12RegisterFileE
+__ZN3JSC12RegisterFile15setGlobalObjectEPNS_14JSGlobalObjectE
+__ZN3JSC17ProgramExecutable15generateJITCodeEPNS_9ExecStateEPNS_14ScopeChainNodeE
 __ZN3JSC3JIT14privateCompileEv
 __ZN3JSC3JIT22privateCompileMainPassEv
 __ZN3JSC3JIT13emit_op_enterEPNS_11InstructionE
 __ZN3JSC3JIT14privateCompileEv
 __ZN3JSC3JIT22privateCompileMainPassEv
 __ZN3JSC3JIT13emit_op_enterEPNS_11InstructionE
-__ZN3JSC3JIT16emit_op_new_funcEPNS_11InstructionE
-__ZN3JSC20MacroAssemblerX86_648storePtrENS_22AbstractMacroAssemblerINS_12X86AssemblerEE6ImmPtrENS3_15ImplicitAddressE
-__ZN3JSC11JITStubCall4callEj
-__ZN3WTF6VectorIN3JSC10CallRecordELm0EE14expandCapacityEm
 __ZN3JSC3JIT11emit_op_movEPNS_11InstructionE
 __ZN3JSC3JIT11emit_op_movEPNS_11InstructionE
-__ZN3JSC3JIT20emit_op_new_func_expEPNS_11InstructionE
-__ZN3JSC3JIT12emit_op_callEPNS_11InstructionE
-__ZN3JSC3JIT13compileOpCallENS_8OpcodeIDEPNS_11InstructionEj
+__ZN3JSC3JIT22emit_op_resolve_globalEPNS_11InstructionEb
+__ZN3JSC23MacroAssemblerX86Common4moveENS_12X86Registers10RegisterIDES2_
+__ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEmPKS2_
 __ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEm
 __ZN3WTF6VectorIN3JSC13SlowCaseEntryELm0EE14expandCapacityEm
-__ZN3JSC3JIT11emit_op_endEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_get_by_idEPNS_11InstructionE
+__ZN3JSC3JIT21compileGetByIdHotPathEiiPNS_10IdentifierEj
+__ZN3JSC3JIT17emit_op_constructEPNS_11InstructionE
+__ZN3JSC3JIT13compileOpCallENS_8OpcodeIDEPNS_11InstructionEj
 __ZN3JSC11JITStubCall4callEv
 __ZN3JSC11JITStubCall4callEv
+__ZN3WTF6VectorIN3JSC10CallRecordELm0EE14expandCapacityEm
+__ZN3JSC3JIT24emit_op_construct_verifyEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_method_checkEPNS_11InstructionE
+__ZN3WTF6VectorIN3JSC25MethodCallCompilationInfoELm0EE14expandCapacityEm
+__ZN3JSC3JIT12emit_op_callEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_put_by_idEPNS_11InstructionE
+__ZN3JSC3JIT11emit_op_endEPNS_11InstructionE
 __ZN3WTF6VectorIN3JSC9JumpTableELm0EE14shrinkCapacityEm
 __ZN3JSC3JIT23privateCompileSlowCasesEv
 __ZN3WTF6VectorIN3JSC9JumpTableELm0EE14shrinkCapacityEm
 __ZN3JSC3JIT23privateCompileSlowCasesEv
-__ZN3JSC3JIT16emitSlow_op_callEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT26emitSlow_op_resolve_globalEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC20MacroAssemblerX86_648storePtrENS_22AbstractMacroAssemblerINS_12X86AssemblerEE6ImmPtrENS3_15ImplicitAddressE
+__ZN3JSC11JITStubCall4callEj
+__ZN3JSC3JIT21emitSlow_op_get_by_idEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT22compileGetByIdSlowCaseEiiPNS_10IdentifierERPNS_13SlowCaseEntryEb
+__ZN3JSC3JIT21emitSlow_op_constructEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSC3JIT21compileOpCallSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryEjNS_8OpcodeIDE
 __ZN3JSC3JIT21compileOpCallSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryEjNS_8OpcodeIDE
+__ZN3JSC3JIT27compileOpConstructSetupArgsEPNS_11InstructionE
+__ZN3JSC3JIT28emitSlow_op_construct_verifyEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT24emitSlow_op_method_checkEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT16emitSlow_op_callEPNS_11InstructionERPNS_13SlowCaseEntryE
 __ZN3JSC3JIT22compileOpCallSetupArgsEPNS_11InstructionE
 __ZN3JSC3JIT22compileOpCallSetupArgsEPNS_11InstructionE
-__ZN3JSC9CodeBlock10setJITCodeERNS_10JITCodeRefE
+__ZN3JSC3JIT21emitSlow_op_put_by_idEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3WTF6VectorIN3JSC18MethodCallLinkInfoELm0EE14expandCapacityEm
 __ZN3JSC17BytecodeGenerator18dumpsGeneratedCodeEv
 __ZN3JSC17BytecodeGenerator18dumpsGeneratedCodeEv
-__ZN3WTF10RefCountedIN3JSC14ExecutablePoolEE5derefEv
 _ctiTrampoline
 _ctiTrampoline
-__ZN3JSC8JITStubs15cti_op_new_funcEPPv
-__ZN3JSC12FuncDeclNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC8JITStubs19cti_op_new_func_expEPPv
-__ZN3JSC12FuncExprNode12makeFunctionEPNS_9ExecStateEPNS_14ScopeChainNodeE
-__ZN3JSC8JITStubs22cti_op_call_JSFunctionEPPv
-__ZN3JSC16FunctionBodyNode15generateJITCodeEPNS_14ScopeChainNodeE
-__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator8newLabelEv
+_cti_op_resolve_global
+_cti_op_get_by_id
+__ZNK3JSC7JSValue3getEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+_cti_op_construct_NotJSConstruct
+__ZN3JSC15DateConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL28constructWithDateConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC13constructDateEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC12DateInstanceC1EPNS_9ExecStateEd
+__ZN3JSC12DateInstanceC2EPNS_9ExecStateEd
+__ZN3WTF8timeClipEd
+_cti_op_get_by_id_method_check
+__ZN3JSC13DatePrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC9Structure13hasTransitionEPN7WebCore10StringImplEj
+_cti_vm_lazyLinkCall
+__ZN3JSCL20dateProtoFuncGetTimeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12DateInstance9classInfoEv
+_cti_op_put_by_id
+__ZN3JSC14JSGlobalObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC8JSObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC17ProgramExecutableD0Ev
+__ZN3JSC16ProgramCodeBlockD0Ev
+__ZN3WTF9HashTableIPN3JSC15GlobalCodeBlockES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS
+__ZN3JSC17StructureStubInfo5derefEv
+__ZN7WebCore6String8truncateEj
+__ZN3JSC5Lexer10skipRegExpEv
+__ZNK3JSC14ExpressionNode10isLocationEv
+__ZN3WTF6VectorIPN3JSC16FunctionBodyNodeELm0EE14expandCapacityEm
+__ZNK3JSC18EmptyStatementNode16isEmptyStatementEv
+__ZN3WTF6VectorISt4pairIPKN3JSC10IdentifierEjELm0EE14expandCapacityEm
+__ZN3JSC8JSObject12removeDirectERKNS_10IdentifierE
+__ZN3JSC9Structure24removePropertyTransitionEPS0_RKNS_10IdentifierERm
+__ZN3JSC9Structure6removeERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator12addGlobalVarERKNS_10IdentifierEbRPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15emitNewFunctionEPNS_10RegisterIDEPNS_16FunctionBodyNodeE
+__ZN3WTF6VectorINS_6RefPtrIN3JSC18FunctionExecutableEEELm0EE14expandCapacityEm
+__ZN3JSC9Structure31removePropertyWithoutTransitionERKNS_10IdentifierE
+__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZNK3JSC7UString14toStrictUInt32EPb
+__ZN7WebCore12AtomicString4findEPKtjj
+__ZN3WTF9HashTableINS_6RefPtrIN7WebCore10StringImplEEESt4pairIS4_N3JSC16SymbolTableEntryEENS_18PairFirstExtractorIS8_EENS6_17Id
+__ZN3JSCL30comparePropertyMapEntryIndicesEPKvS1_
+__ZN3JSC13AssignDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC17BytecodeGenerator8emitMoveEPNS_10RegisterIDES2_
+__ZN3JSC17ObjectLiteralNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13emitNewObjectEPNS_10RegisterIDE
+__ZN3JSC21FunctionCallValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12FuncExprNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator25emitNewFunctionExpressionEPNS_10RegisterIDEPNS_12FuncExprNodeE
+__ZN3JSC12FuncDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC15DotAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator11emitResolveEPNS_10RegisterIDERKNS_10IdentifierE
-__ZN3JSC17BytecodeGenerator18findScopedPropertyERKNS_10IdentifierERiRmbRPNS_8JSObjectE
+__ZN3JSC16VarStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15isLocalConstantERKNS_10IdentifierE
+__ZN3JSC16ArgumentListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC11BooleanNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEb
+__ZN3JSC9ArrayNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitNewArrayEPNS_10RegisterIDEPNS_11ElementNodeE
+__ZN3JSC23FunctionCallResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE
+__ZN3JSC10NumberNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEd
+__ZN3WTF9HashTableIdSt4pairIdN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_9FloatHashIdEENS_14PairHashTraitsINS_10HashTraitsId
+__ZN3JSC10StringNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDERKNS_10IdentifierE
+__ZN3WTF9HashTableIPN7WebCore10StringImplESt4pairIS3_PN3JSC8JSStringEENS_18PairFirstExtractorIS8_EENS5_17IdentifierRepHashENS_1
+__ZN3JSC12SmallStrings27createSingleCharacterStringEPNS_12JSGlobalDataEh
+__ZN3JSC8NullNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15ParserArenaDataIN3WTF6VectorIPNS_16FunctionBodyNodeELm0EEEED1Ev
+__ZN3JSC15ParserArenaDataIN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEED1Ev
+__ZN3JSC3JIT16emit_op_new_funcEPNS_11InstructionE
+__ZN3JSC3JIT18emit_op_new_objectEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_new_func_expEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_new_arrayEPNS_11InstructionE
+__ZN3JSC3JIT25emit_op_resolve_with_baseEPNS_11InstructionE
+_cti_op_new_func
+__ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_18FunctionExecutableEEEPNS_14ScopeChainNodeE
+_cti_op_new_object
+_cti_op_new_func_exp
+_cti_op_call_JSFunction
+__ZN3JSC18FunctionExecutable15generateJITCodeEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3WTF7HashSetINS_6RefPtrIN7WebCore10StringImplEEEN3JSC17IdentifierRepHashENS_10HashTraitsIS4_EEE3addERKS4_
+__ZN3WTF9HashTableINS_6RefPtrIN7WebCore10StringImplEEES4_NS_17IdentityExtractorIS4_EEN3JSC17IdentifierRepHashENS_10HashTraitsIS
+__ZN3JSC17BytecodeGenerator6addVarERKNS_10IdentifierEbRPNS_10RegisterIDE
 __ZNK3JSC16JSVariableObject16isVariableObjectEv
 __ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_7JSValueE
 __ZNK3JSC16JSVariableObject16isVariableObjectEv
 __ZN3JSC17BytecodeGenerator16emitGetScopedVarEPNS_10RegisterIDEmiNS_7JSValueE
-__ZN3JSC17BytecodeGenerator11emitGetByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3WTF6VectorIN3JSC17StructureStubInfoELm0EE14expandCapacityEm
-__ZN3JSC17BytecodeGenerator11addConstantERKNS_10IdentifierE
-__ZN3WTF7HashMapINS_6RefPtrIN3JSC7UString3RepEEEiNS2_17IdentifierRepHashENS_10HashTraitsIS5_EENS2_17BytecodeGenerator28Identifi
-__ZN3WTF9HashTableINS_6RefPtrIN3JSC7UString3RepEEESt4pairIS5_iENS_18PairFirstExtractorIS7_EENS2_17IdentifierRepHashENS_14PairHa
+__ZNK3JSC13StatementNode12isReturnNodeEv
+__ZN3JSC3JIT29emit_op_enter_with_activationEPNS_11InstructionE
+__ZN3JSC3JIT22emit_op_get_global_varEPNS_11InstructionE
+__ZN3JSC3JIT29emitGetVariableObjectRegisterENS_12X86Registers10RegisterIDEiS2_
+__ZN3JSC3JIT27emit_op_tear_off_activationEPNS_11InstructionE
+__ZN3JSC11JITStubCall11addArgumentEjNS_12X86Registers10RegisterIDE
+__ZN3JSC3JIT11emit_op_retEPNS_11InstructionE
+_cti_register_file_check
+_cti_op_push_activation
+__ZN3JSC12JSActivationC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_18FunctionExecutableEEE
+__ZN3JSC12JSActivationC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_18FunctionExecutableEEE
+_cti_op_tear_off_activation
+_cti_op_ret_scopeChain
+__ZN3JSC10JSFunction18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC9Structure18transitionTableAddERKSt4pairIN3WTF6RefPtrIN7WebCore10StringImplEEEjEPS0_PNS_6JSCellE
+__ZN3WTF7HashMapISt4pairINS_6RefPtrIN7WebCore10StringImplEEEjES1_IPN3JSC9StructureES9_ENS7_28StructureTransitionTableHashENS7_3
+__ZN3WTF9HashTableISt4pairINS_6RefPtrIN7WebCore10StringImplEEEjES1_IS6_S1_IPN3JSC9StructureES9_EENS_18PairFirstExtractorISB_EEN
+_cti_op_new_array
+__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7ArgListE
+_cti_op_construct_JSConstruct
+__ZNK3JSC10NumberNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC8ThisNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC3JIT20emit_op_convert_thisEPNS_11InstructionE
+__ZN3JSC3JIT24emitSlow_op_convert_thisEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_resolve_with_base
+__ZN3JSC10JSFunction11getCallDataERNS_8CallDataE
+__ZNK3JSC7ArgList8getSliceEiRS0_
+__ZN3JSC9Structure22materializePropertyMapEv
+_cti_op_end
+__ZNK7WebCore6String7toFloatEPb
+__ZN7WebCore10StringImpl7toFloatEPb
+__ZN7WebCore17charactersToFloatEPKtmPb
+__ZN7WebCoreeqERKNS_12AtomicStringEPKc
+__ZNK7WebCore6String5toIntEPb
+__ZN7WebCore10StringImpl5toIntEPb
+__ZN7WebCore15charactersToIntEPKtmPb
+__ZN7WebCore6String6numberEi
+__ZNK7WebCore6String11toIntStrictEPbi
+__ZN7WebCore10StringImpl11toIntStrictEPbi
+__ZN7WebCore21charactersToIntStrictEPKtmPbi
+__ZN7WebCore10StringImpl7replaceEPS0_S1_
+__ZN7WebCore6String6numberEt
+__ZL11makeDivNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
+__ZNK3JSC10NumberNode8isNumberEv
+__ZN3WTF6VectorIPvLm0EE14expandCapacityEm
+__ZN3WTF6VectorIjLm16EE6resizeEm
+__ZN3WTFL7multaddERNS_6BigIntEii
+__ZN3WTF6VectorIjLm16EEaSERKS1_
+__ZN3WTFL4multERNS_6BigIntERKS0_
+__ZL11makeAddNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
+__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE15reserveCapacityEm
+__ZL14makePrefixNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeENS_8OperatorEiii
+__ZN3WTF6VectorIPN3JSC10RegisterIDELm32EE15reserveCapacityEm
+__ZN3JSC16PropertyListNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15ConditionalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator8newLabelEv
+__ZNK3JSC14ExpressionNode26hasConditionContextCodegenEv
 __ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE
 __ZN3JSC17BytecodeGenerator15emitJumpIfFalseEPNS_10RegisterIDEPNS_5LabelE
-__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
 __ZN3JSC17BytecodeGenerator8emitJumpEPNS_5LabelE
 __ZN3JSC17BytecodeGenerator9emitLabelEPNS_5LabelE
-__ZN3WTF6VectorIjLm0EE15reserveCapacityEm
+__ZN3WTF6VectorIjLm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator14emitPutByIndexEPNS_10RegisterIDEjS2_
 __ZN3JSC6IfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __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_
+__ZNK3JSC14LogicalNotNode26hasConditionContextCodegenEv
+__ZN3JSC11UnaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11emitUnaryOpENS_8OpcodeIDEPNS_10RegisterIDES3_
+__ZNK3JSC10StringNode6isPureERNS_17BytecodeGeneratorE
+__ZNK3JSC14ExpressionNode5isAddEv
+__ZN3JSC7ForNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13newLabelScopeENS_10LabelScope4TypeEPKNS_10IdentifierE
+__ZN3JSC19BracketAccessorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitGetByValEPNS_10RegisterIDES2_S2_
+__ZN3JSC17PrefixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator10emitPreIncEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitJumpIfTrueEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC3JIT11emit_op_divEPNS_11InstructionE
+__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common9ConditionENS_12X86Registers10RegisterIDES4_
+__ZN3JSC12X86Assembler11cvtsi2sd_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE
+__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDE
+__ZN3JSC12X86Assembler7movq_rrENS_12X86Registers10RegisterIDENS1_13XMMRegisterIDE
+__ZN3JSC23MacroAssemblerX86Common4moveENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5Imm32ENS_12X86Registers10RegisterIDE
+__ZN3JSC15AssemblerBuffer7putByteEi
 __ZN3JSC3JIT14emit_op_jfalseEPNS_11InstructionE
 __ZN3JSC3JIT14emit_op_jfalseEPNS_11InstructionE
-__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common9ConditionENS_3X8610RegisterIDENS_22AbstractMacroAssembler
-__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common9ConditionENS_3X8610RegisterIDES4_
+__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common9ConditionENS_12X86Registers10RegisterIDENS_22AbstractMacr
 __ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEmPKS2_
 __ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEm
 __ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEmPKS2_
 __ZN3WTF6VectorIN3JSC9JumpTableELm0EE14expandCapacityEm
-__ZN3JSC3JIT20emit_op_resolve_funcEPNS_11InstructionE
 __ZN3JSC3JIT11emit_op_jmpEPNS_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
+__ZN3JSC3JIT20emit_op_put_by_indexEPNS_11InstructionE
+__ZN3JSC3JIT13emit_op_jtrueEPNS_11InstructionE
+__ZN3JSC3JIT11emit_op_addEPNS_11InstructionE
+__ZN3JSC3JIT18emit_op_get_by_valEPNS_11InstructionE
+__ZN3JSC20MacroAssemblerX86_649branchPtrENS_23MacroAssemblerX86Common9ConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE
+__ZN3JSC12X86Assembler23X86InstructionFormatter11oneByteOp64ENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii
+__ZN3JSC3JIT15emit_op_pre_incEPNS_11InstructionE
+__ZN3JSC3JIT16emitTimeoutCheckEv
+__ZN3JSC3JIT13emit_op_jlessEPNS_11InstructionE
+__ZN3JSC3JIT15emitSlow_op_divEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT18emitSlow_op_jfalseEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_9ConditionENS_12X86Registers10RegisterIDENS_22AbstractMacroAssemblerINS_12X
+__ZN3JSC3JIT17emitSlow_op_jtrueEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT22emitSlow_op_get_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT27stringGetByValStubGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC15AssemblerBuffer14executableCopyEPNS_14ExecutablePoolE
+__ZN3JSC3JIT19emitSlow_op_pre_incEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC11JITStubCall11addArgumentENS_12X86Registers10RegisterIDE
+__ZN3JSC3JIT17emitSlow_op_jlessEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC23MacroAssemblerX86Common12branchDoubleENS0_15DoubleConditionENS_12X86Registers13XMMRegisterIDES3_
+__ZNK3JSC13LogicalOpNode26hasConditionContextCodegenEv
+__ZN3JSC13LogicalOpNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b
+__ZN3JSC21ReadModifyResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC3JIT11emit_op_subEPNS_11InstructionE
+__ZN3JSC3JIT20compileBinaryArithOpENS_8OpcodeIDEjjjNS_12OperandTypesE
+__ZN3JSC3JIT15emitSlow_op_subEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT28compileBinaryArithOpSlowCaseENS_8OpcodeIDERPNS_13SlowCaseEntryEjjjNS_12OperandTypesEbb
+__ZN3JSC3JIT15emitSlow_op_addEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZNK3JSC14JSGlobalObject14isDynamicScopeERb
+_cti_op_jtrue
+__ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
+__ZNK3JSC8JSObject24getPropertySpecificValueEPNS_9ExecStateERKNS_10IdentifierERPNS_6JSCellE
+__ZN3JSC27ctiPatchCallByReturnAddressEPNS_9CodeBlockENS_16ReturnAddressPtrENS_11FunctionPtrE
+__ZN3JSC3JIT8linkCallEPNS_10JSFunctionEPNS_9CodeBlockES4_RNS_7JITCodeEPNS_12CallLinkInfoEiPNS_12JSGlobalDataE
+_cti_op_add
+__ZN3JSC13jsAddSlowCaseEPNS_9ExecStateENS_7JSValueES2_
+__ZNK3JSC8JSString11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZNK3JSC7JSValue8toStringEPNS_9ExecStateE
+__ZN3JSC7UString4fromEi
+__ZNK3JSC8JSString11resolveRopeEPNS_9ExecStateE
+__ZN3WTF13tryFastMallocEm
+__ZN7WebCore10StringImpl4findEPKcib
+__ZN3JSC13LogicalOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode6isNullEv
+__ZN3JSC3JIT11emit_op_neqEPNS_11InstructionE
+__ZN3JSC12X86Assembler8shll_i8rEiNS_12X86Registers10RegisterIDE
+__ZN3JSC12X86Assembler6orl_irEiNS_12X86Registers10RegisterIDE
+__ZN3JSC3JIT15emitSlow_op_neqEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_call_arityCheck
+_cti_op_eq
+__ZN3JSC9JITThunks15tryCacheGetByIDEPNS_9ExecStateEPNS_9CodeBlockENS_16ReturnAddressPtrENS_7JSValueERKNS_10IdentifierERKNS_12Pr
+__ZN3JSC14StructureChainC1EPNS_9StructureE
+__ZN3JSC14StructureChainC2EPNS_9StructureE
+__ZN3JSC3JIT26privateCompileGetByIdChainEPNS_17StructureStubInfoEPNS_9StructureEPNS_14StructureChainEmRKNS_10IdentifierERKNS_12
+__ZN3JSC3JIT22compileGetDirectOffsetEPNS_8JSObjectENS_12X86Registers10RegisterIDES4_m
+_cti_op_get_by_id_self_fail
+__ZN3JSC3JIT29privateCompileGetByIdSelfListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureERKNS_1
+_cti_op_get_by_id_custom_stub
+__ZN3JSC10MathObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL16mathProtoFuncMaxEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZL17combineCommaNodesPN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_
+__ZNK3JSC14ExpressionNode11isCommaNodeEv
+__ZNK3JSC9CommaNode11isCommaNodeEv
+__ZN3JSC9CommaNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC19ReverseBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC9BreakNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11breakTargetERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator14emitJumpScopesEPNS_5LabelEi
+__ZN3JSC9CommaNodeD1Ev
+__ZN3JSC3JIT14emit_op_jnlessEPNS_11InstructionE
+__ZN3JSC3JIT18emitSlow_op_jnlessEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+_cti_op_jless
+__ZN3JSC3JIT33privateCompilePatchGetArrayLengthENS_16ReturnAddressPtrE
+__ZN3JSC3JIT16patchGetByIdSelfEPNS_9CodeBlockEPNS_17StructureStubInfoEPNS_9StructureEmNS_16ReturnAddressPtrE
+__ZNK3JSC7AddNode5isAddEv
+__ZN3JSC9JITThunks15tryCachePutByIDEPNS_9ExecStateEPNS_9CodeBlockENS_16ReturnAddressPtrENS_7JSValueERKNS_15PutPropertySlotEPNS_
+_cti_op_negate
+__ZN3JSC7UString4fromEj
+__ZL12makeMultNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
+__ZN3JSC9EqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitEqualityOpENS_8OpcodeIDEPNS_10RegisterIDES3_S3_
+__ZN3JSC3JIT11emit_op_notEPNS_11InstructionE
+__ZN3JSC3JIT11emit_op_mulEPNS_11InstructionE
+__ZN3JSC3JIT10emit_op_eqEPNS_11InstructionE
+__ZN3JSC3JIT15emitSlow_op_notEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT15emitSlow_op_mulEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT14emitSlow_op_eqEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_not
+__ZN3JSC17ReadModifyDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator10emitPreDecEPNS_10RegisterIDE
+__ZN3JSC3JIT16emit_op_jnlesseqEPNS_11InstructionE
+__ZN3JSC3JIT15emit_op_jlesseqEPNS_11InstructionEb
+__ZN3JSC3JIT15emit_op_pre_decEPNS_11InstructionE
+__ZN3JSC3JIT22emit_op_loop_if_lesseqEPNS_11InstructionE
+__ZN3JSC3JIT20emitSlow_op_jnlesseqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT19emitSlow_op_jlesseqEPNS_11InstructionERPNS_13SlowCaseEntryEb
+__ZN3JSC3JIT19emitSlow_op_pre_decEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT26emitSlow_op_loop_if_lesseqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC17powThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC19SpecializedThunkJIT12returnDoubleENS_12X86Registers13XMMRegisterIDE
+__ZN3JSC19SpecializedThunkJITD1Ev
+__ZN3JSCL16mathProtoFuncSinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncMinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18mathProtoFuncRoundEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncLogEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC3JIT20patchMethodCallProtoEPNS_9CodeBlockERNS_18MethodCallLinkInfoEPNS_10JSFunctionEPNS_9StructureEPNS_8JSObjectENS_16R
+__ZN3JSC3JIT31privateCompilePutByIdTransitionEPNS_17StructureStubInfoEPNS_9StructureES4_mPNS_14StructureChainENS_16ReturnAddres
+__ZN3JSC3JIT13testPrototypeEPNS_9StructureERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListE
+__ZN3JSCL16mathProtoFuncAbsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_jlesseq
+__ZN3WTF6VectorIPN3JSC12CallLinkInfoELm0EE15reserveCapacityEm
+__ZN3JSC10IfElseNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17TypeOfResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC7TryNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator9emitCatchEPNS_10RegisterIDEPNS_5LabelES4_
+__ZN3JSC9CodeBlock25createRareDataIfNecessaryEv
+__ZN3WTF6VectorIN3JSC11HandlerInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator16emitPushNewScopeEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3WTF6VectorIN3JSC18ControlFlowContextELm0EE14expandCapacityEm
+__ZN3JSC15TypeOfValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSCeqERKNS_7UStringEPKc
+__ZN3JSC17BytecodeGenerator12emitPopScopeEv
+__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14shrinkCapacityEm
+__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14shrinkCapacityEm
+__ZN3JSC3JIT13emit_op_catchEPNS_11InstructionE
+__ZN3JSC3JIT22emit_op_push_new_scopeEPNS_11InstructionE
+__ZN3JSC3JIT15emit_op_resolveEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_resolve_baseEPNS_11InstructionE
+__ZN3JSC3JIT17emit_op_pop_scopeEPNS_11InstructionE
+__ZL15makePostfixNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeENS_8OperatorEiii
+__ZN3JSC12BinaryOpNode10emitStrcatERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_PNS_21ReadModifyResolveNodeE
+__ZNK3JSC10StringNode8isStringEv
+__ZNK3JSC14ExpressionNode8isStringEv
+__ZN3JSC17BytecodeGenerator15emitToPrimitiveEPNS_10RegisterIDES2_
+__ZN3JSC17BytecodeGenerator10emitStrcatEPNS_10RegisterIDES2_i
+__ZN3JSC18PostfixResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC3JIT11emit_op_modEPNS_11InstructionE
+__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_9ConditionENS_12X86Registers10RegisterIDENS_22AbstractMacroAssemblerINS_12X86Ass
+__ZN3JSC3JIT20emit_op_to_primitiveEPNS_11InstructionE
+__ZN3JSC23MacroAssemblerX86Common4moveENS_22AbstractMacroAssemblerINS_12X86AssemblerEE6ImmPtrENS_12X86Registers10RegisterIDE
+__ZN3JSC3JIT14emit_op_strcatEPNS_11InstructionE
+__ZN3JSC3JIT15emitSlow_op_modEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT24emitSlow_op_to_primitiveEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSCL18mathProtoFuncFloorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL17mathProtoFuncCeilEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_strcat
+__ZNK3JSC19BracketAccessorNode10isLocationEv
+__ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv
+__ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_
+__ZN3JSC3JIT18emit_op_put_by_valEPNS_11InstructionE
+__ZN3JSC3JIT22emitSlow_op_put_by_valEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC14ArrayPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC14LogicalNotNode30emitBytecodeInConditionContextERNS_17BytecodeGeneratorEPNS_5LabelES4_b
+__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC15StringPrototype18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL21stringProtoFuncSubstrEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue9toIntegerEPNS_9ExecStateE
+__ZN7WebCore10StringImpl6createEN3WTF10PassRefPtrIS0_EEjj
+__ZN3WTF6RefPtrIN7WebCore10StringImplEED1Ev
+__ZN3JSCL18arrayProtoFuncJoinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZNK3JSC8JSObject12toThisObjectEPNS_9ExecStateE
 __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
+__ZN3WTF7HashSetIPN3JSC8JSObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC8JSObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZNK3JSC8JSObject3getEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC15JSStringBuilder5buildEPNS_9ExecStateE
+__ZN3WTF6VectorItLm64EE17tryExpandCapacityEm
+__ZN3JSCL18arrayProtoFuncPushEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray4pushEPNS_9ExecStateENS_7JSValueE
+__ZN3WTF14tryFastReallocEPvm
+__ZN3JSC4Heap15recordExtraCostEm
+__ZN3JSC17BytecodeGenerator16emitPutScopedVarEmiPNS_10RegisterIDENS_7JSValueE
+__ZN3JSC3JIT22emit_op_put_scoped_varEPNS_11InstructionE
+__ZN3JSC3JIT29emitPutVariableObjectRegisterENS_12X86Registers10RegisterIDES2_i
+__ZN3JSC3JIT22emit_op_put_global_varEPNS_11InstructionE
+_cti_op_put_by_index
+__ZN3JSC7JSArray3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC7JSArray11putSlowCaseEPNS_9ExecStateEjNS_7JSValueE
+__ZNK3JSC11BooleanNode6isPureERNS_17BytecodeGeneratorE
+__ZN3JSC10JSFunction3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZNK7WebCore12AtomicString5lowerEv
+_cti_op_get_by_id_proto_list
+__ZN3JSC3JIT30privateCompileGetByIdChainListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureEPNS_1
+__ZN3JSC3JIT22emit_op_get_scoped_varEPNS_11InstructionE
+_cti_op_put_by_val
+__ZNK3JSC12JSActivation14isDynamicScopeERb
+__ZN3JSC24ApplyFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZNK3JSC14ExpressionNode13isSimpleArrayEv
+__ZN3JSC17BytecodeGenerator26emitJumpIfNotFunctionApplyEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC17BytecodeGenerator22willResolveToArgumentsERKNS_10IdentifierE
+__ZN3JSC17BytecodeGenerator15emitLoadVarargsEPNS_10RegisterIDES2_
+__ZN3JSC17BytecodeGenerator15emitCallVarargsEPNS_10RegisterIDES2_S2_S2_jjj
+__ZN3JSC3JIT16emit_op_jneq_ptrEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_load_varargsEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_call_varargsEPNS_11InstructionE
+__ZN3JSC3JIT20compileOpCallVarargsEPNS_11InstructionE
+__ZN3JSC3JIT29compileOpCallVarargsSetupArgsEPNS_11InstructionE
+__ZN3JSC3JIT24emitSlow_op_call_varargsEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT28compileOpCallVarargsSlowCaseEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC14ExecutablePool13systemReleaseERKNS0_10AllocationE
+_JSStringCreateWithCFString
+_JSStringRetain
+_JSStringRelease
+_JSEvaluateScript
+__ZN3JSC4Heap14registerThreadEv
+__ZNK14OpaqueJSString7ustringEv
+__ZN3JSC7UStringC1EPKtj
+__ZN3JSC5Lexer10scanRegExpERPKNS_10IdentifierES4_t
+__ZN3JSC18ConstStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13ConstDeclNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13ConstDeclNode14emitCodeSingleERNS_17BytecodeGeneratorE
+__ZN3JSC17BytecodeGenerator16constRegisterForERKNS_10IdentifierE
 __ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
 __ZN3JSC10RegExpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringES5_
+__ZNK3JSC7UString4findEtj
 __ZN3JSC4Yarr15jitCompileRegexEPNS_12JSGlobalDataERNS0_14RegexCodeBlockERKNS_7UStringERjRPKcbb
 __ZN3JSC4Yarr12compileRegexERKNS_7UStringERNS0_12RegexPatternE
 __ZN3JSC4Yarr15jitCompileRegexEPNS_12JSGlobalDataERNS0_14RegexCodeBlockERKNS_7UStringERjRPKcbb
 __ZN3JSC4Yarr12compileRegexERKNS_7UStringERNS0_12RegexPatternE
+__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE5parseEv
 __ZN3JSC4Yarr18PatternDisjunction17addNewAlternativeEv
 __ZN3JSC4Yarr18PatternDisjunction17addNewAlternativeEv
-__ZN3WTF6VectorIPN3JSC4Yarr18PatternAlternativeELm0EE14expandCapacityEm
-__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE11parseTokensEv
+__ZN3WTF6VectorIPN3JSC4Yarr18PatternAlternativeELm0EE15reserveCapacityEm
+__ZN3JSC4Yarr23RegexPatternConstructor20atomPatternCharacterEt
 __ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEmPKS3_
 __ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEm
 __ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE11parseEscapeILb0ES2_EEbRT0_
 __ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEmPKS3_
 __ZN3WTF6VectorIN3JSC4Yarr11PatternTermELm0EE14expandCapacityEm
 __ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE11parseEscapeILb0ES2_EEbRT0_
-__ZN3JSC4Yarr23RegexPatternConstructor25atomBuiltInCharacterClassENS0_23BuiltInCharacterClassIDEb
-__ZN3JSC4Yarr14wordcharCreateEv
-__ZN3WTF6VectorItLm0EE14expandCapacityEm
-__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEmPKS3_
-__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEm
-__ZN3WTF6VectorIPN3JSC4Yarr14CharacterClassELm0EE14expandCapacityEmPKS4_
-__ZN3WTF6VectorIPN3JSC4Yarr14CharacterClassELm0EE14expandCapacityEm
 __ZN3JSC4Yarr14RegexGenerator19generateDisjunctionEPNS0_18PatternDisjunctionE
 __ZN3JSC4Yarr14RegexGenerator19generateDisjunctionEPNS0_18PatternDisjunctionE
-__ZN3JSC12X86Assembler7addl_irEiNS_3X8610RegisterIDE
-__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_9ConditionENS_3X8610RegisterIDES3_
-__ZN3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpList6appendENS2_4JumpE
+__ZN3JSC12X86Assembler7addl_irEiNS_12X86Registers10RegisterIDE
+__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_9ConditionENS_12X86Registers10RegisterIDES3_
 __ZN3JSC4Yarr14RegexGenerator12generateTermERNS1_19TermGenerationStateE
 __ZN3JSC4Yarr14RegexGenerator12generateTermERNS1_19TermGenerationStateE
-__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_9ConditionENS_3X8610RegisterIDENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5I
+__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_12X86Registers10RegisterIDES4_ii
 __ZN3JSC4Yarr14RegexGenerator19TermGenerationState15jumpToBacktrackENS_22AbstractMacroAssemblerINS_12X86AssemblerEE4JumpEPNS_14
 __ZN3JSC4Yarr14RegexGenerator19TermGenerationState15jumpToBacktrackENS_22AbstractMacroAssemblerINS_12X86AssemblerEE4JumpEPNS_14
-__ZN3JSC4Yarr14RegexGenerator13readCharacterEiNS_3X8610RegisterIDE
-__ZN3JSC4Yarr14RegexGenerator19matchCharacterClassENS_3X8610RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpLis
-__ZN3JSC4Yarr14RegexGenerator24matchCharacterClassRangeENS_3X8610RegisterIDERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8Ju
+__ZN3JSC4Yarr14RegexGenerator19jumpIfCharNotEqualsEti
+__ZN3JSC12X86Assembler7subl_irEiNS_12X86Registers10RegisterIDE
 __ZN3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpList4linkEPS2_
 __ZN3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpList4linkEPS2_
-__ZN3JSC23MacroAssemblerX86Common4jumpEv
-__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EED1Ev
-__ZN3JSC4Yarr14RegexGenerator28generateCharacterClassGreedyERNS1_19TermGenerationStateE
-__ZN3JSC12X86Assembler7subl_irEiNS_3X8610RegisterIDE
-__ZN3JSC15AssemblerBuffer4growEv
+__ZN3WTF15deleteAllValuesIPN3JSC4Yarr18PatternDisjunctionELm4EEEvRKNS_6VectorIT_XT0_EEE
 __ZN3WTF15deleteAllValuesIPN3JSC4Yarr14CharacterClassELm0EEEvRKNS_6VectorIT_XT0_EEE
 __ZN3WTF15deleteAllValuesIPN3JSC4Yarr14CharacterClassELm0EEEvRKNS_6VectorIT_XT0_EEE
-__ZN3JSC17BytecodeGenerator13emitNewRegExpEPNS_10RegisterIDEPNS_6RegExpE
-__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
-__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
-__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
-__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC8JSString12toThisStringEPNS_9ExecStateE
-__ZNK3JSC6JSCell8isObjectEPKNS_9ClassInfoE
-__ZNK3JSC6JSCell9classInfoEv
-__ZN3JSC4Yarr23RegexPatternConstructor20atomPatternCharacterEt
+__ZN3JSC17BytecodeGenerator8emitLoadEPNS_10RegisterIDEPNS_6RegExpE
+__ZN3JSC12RegExpObjectC1EN3WTF17NonNullPassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
+__ZN3JSC12RegExpObjectC2EN3WTF17NonNullPassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
+__ZN3JSC4Yarr23RegexPatternConstructor30atomParenthesesSubpatternBeginEb
 __ZN3JSC4Yarr25CharacterClassConstructor7putCharEt
 __ZN3JSC4Yarr25CharacterClassConstructor9addSortedERN3WTF6VectorItLm0EEEt
 __ZN3JSC4Yarr25CharacterClassConstructor7putCharEt
 __ZN3JSC4Yarr25CharacterClassConstructor9addSortedERN3WTF6VectorItLm0EEEt
+__ZN3WTF6VectorItLm0EE14expandCapacityEm
 __ZN3JSC4Yarr23RegexPatternConstructor21atomCharacterClassEndEv
 __ZN3JSC4Yarr23RegexPatternConstructor21atomCharacterClassEndEv
+__ZN3WTF6VectorIPN3JSC4Yarr14CharacterClassELm0EE14expandCapacityEmPKS4_
+__ZN3WTF6VectorIPN3JSC4Yarr14CharacterClassELm0EE14expandCapacityEm
+__ZN3WTF6VectorIPN3JSC4Yarr18PatternDisjunctionELm4EE14expandCapacityEm
 __ZN3JSC4Yarr23RegexPatternConstructor23setupDisjunctionOffsetsEPNS0_18PatternDisjunctionEjj
 __ZN3JSC4Yarr14RegexGenerator25generateParenthesesSingleERNS1_19TermGenerationStateE
 __ZN3JSC4Yarr14RegexGenerator30generateParenthesesDisjunctionERNS0_11PatternTermERNS1_19TermGenerationStateEj
 __ZN3WTF6VectorIN3JSC4Yarr14RegexGenerator26AlternativeBacktrackRecordELm0EE14expandCapacityEm
 __ZN3JSC4Yarr23RegexPatternConstructor23setupDisjunctionOffsetsEPNS0_18PatternDisjunctionEjj
 __ZN3JSC4Yarr14RegexGenerator25generateParenthesesSingleERNS1_19TermGenerationStateE
 __ZN3JSC4Yarr14RegexGenerator30generateParenthesesDisjunctionERNS0_11PatternTermERNS1_19TermGenerationStateEj
 __ZN3WTF6VectorIN3JSC4Yarr14RegexGenerator26AlternativeBacktrackRecordELm0EE14expandCapacityEm
-__ZN3JSC4Yarr14RegexGenerator19jumpIfCharNotEqualsEti
-__ZN3JSC12X86Assembler23X86InstructionFormatter9oneByteOpENS0_15OneByteOpcodeIDEiNS_3X8610RegisterIDES4_ii
-__ZN3JSC4Yarr14RegexGenerator19TermGenerationState15jumpToBacktrackERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListEP
-__ZN3JSC17RegExpConstructor12performMatchEPNS_6RegExpERKNS_7UStringEiRiS6_PPi
-__ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF11OwnArrayPtrIiEE
-__ZN3JSC4Yarr12executeRegexERNS0_14RegexCodeBlockEPKtjjPii
-__ZN3JSC8JITStubs17cti_op_new_regexpEPPv
-__ZN3JSC12RegExpObjectC1EN3WTF10PassRefPtrINS_9StructureEEENS2_INS_6RegExpEEE
+__ZN3JSC4Yarr14RegexGenerator28generateCharacterClassGreedyERNS1_19TermGenerationStateE
+__ZN3JSC4Yarr14RegexGenerator19matchCharacterClassENS_12X86Registers10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86Assembler
+__ZN3JSC23MacroAssemblerX86Common4jumpEv
+__ZN3JSC4Yarr14RegexGenerator13readCharacterEiNS_12X86Registers10RegisterIDE
+__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+_JSContextGetGlobalObject
+__ZN3WTF13wtfThreadDataEv
+_JSClassCreate
+__ZN13OpaqueJSClass6createEPK17JSClassDefinition
+__ZN13OpaqueJSClassC2EPK17JSClassDefinitionPS_
+__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b
+_JSClassRetain
+_JSObjectMake
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE4initEPNS_9ExecStateE
+__ZN13OpaqueJSClass9prototypeEPN3JSC9ExecStateE
+__ZN13OpaqueJSClass11contextDataEPN3JSC9ExecStateE
+__ZN3WTF9HashTableIP13OpaqueJSClassSt4pairIS2_P24OpaqueJSClassContextDataENS_18PairFirstExtractorIS6_EENS_7PtrHashIS2_EENS_14Pa
+__ZN24OpaqueJSClassContextDataC2EP13OpaqueJSClass
+_JSStringCreateWithUTF8CString
+_JSObjectSetProperty
+__ZN3JSC12APIEntryShimC1EPNS_9ExecStateEb
+__ZNK14OpaqueJSString10identifierEPN3JSC12JSGlobalDataE
+_JSClassRelease
+_JSContextGetGlobalContext
+_JSGlobalContextRetain
+_JSObjectGetProperty
+_JSValueToObject
+_JSValueProtect
+_JSObjectIsFunction
+_JSObjectCallAsFunction
+__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
+__ZN3JSC10JSFunction4callEPNS_9ExecStateENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11Interpreter7executeEPNS_18FunctionExecutableEPNS_9ExecStateEPNS_10JSFunctionEPNS_8JSObjectERKNS_7ArgListEPNS_14ScopeC
+__ZNK3JSC8NullNode6isNullEv
+__ZN3JSC3JIT16emit_op_neq_nullEPNS_11InstructionE
+__ZNK3JSC19JSStaticScopeObject14isDynamicScopeERb
+__ZN3JSC12RegExpObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL19regExpProtoFuncTestEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZNK3JSC12RegExpObject9classInfoEv
 __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
+__ZN3JSC12RegExpObject4testEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC12RegExpObject5matchEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC6RegExp5matchERKNS_7UStringEiPN3WTF6VectorIiLm32EEE
+__ZN3JSC9WhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC15StrictEqualNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC3JIT16emit_op_stricteqEPNS_11InstructionE
+__ZN3JSC3JIT17compileOpStrictEqEPNS_11InstructionENS0_21CompileOpStrictEqTypeE
+__ZN3JSC3JIT17emit_op_nstricteqEPNS_11InstructionE
+__ZN3JSC3JIT20emitSlow_op_stricteqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT21emitSlow_op_nstricteqEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC12ContinueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14continueTargetERKNS_10IdentifierE
+__ZN3JSCL7dateNowEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_get_by_val
+__ZN7WebCore10StringImpl5upperEv
+_cti_op_get_by_id_generic
+_cti_op_put_by_id_fail
 __ZNK3JSC7UString8toUInt32EPbb
 __ZNK3JSC7UString8toDoubleEbb
 __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
+__ZNK3JSC7UString10UTF8StringEb
+__ZN3JSC18globalFuncParseIntEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12nonInlineNaNEv
+__ZN3JSC15toInt32SlowCaseEdRb
+__ZN3JSCL8parseIntERKNS_7UStringEi
+__ZN3JSC15globalFuncIsNaNEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK7WebCore6String8toDoubleEPb
+__ZN7WebCore10StringImpl8toDoubleEPb
 __ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE11parseEscapeILb1ENS3_28CharacterClassParserDelegateEEEbRT0_
 __ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE11parseEscapeILb1ENS3_28CharacterClassParserDelegateEEEbRT0_
-__ZN3JSC4Yarr12digitsCreateEv
+__ZN3JSC4Yarr12spacesCreateEv
+__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEmPKS3_
+__ZN3WTF6VectorIN3JSC4Yarr14CharacterRangeELm0EE14expandCapacityEm
 __ZN3JSC4Yarr25CharacterClassConstructor6appendEPKNS0_14CharacterClassE
 __ZN3JSC4Yarr25CharacterClassConstructor14addSortedRangeERN3WTF6VectorINS0_14CharacterRangeELm0EEEtt
 __ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE28CharacterClassParserDelegate20atomPatternCharacterEt
 __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
-__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
-__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
-__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
-__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
-__ZN3JSC9CodeBlock4markEv
-__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
+__ZN3JSC4Yarr14RegexGenerator24matchCharacterClassRangeENS_12X86Registers10RegisterIDERNS_22AbstractMacroAssemblerINS_12X86Asse
+__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EED1Ev
+_cti_op_nstricteq
+__ZN3JSC27ctiPatchCallByReturnAddressEPNS_9CodeBlockENS_16ReturnAddressPtrENS_21MacroAssemblerCodePtrE
+__ZNK3JSC8JSString9toBooleanEPNS_9ExecStateE
+_cti_op_is_string
+__ZN3JSCL16mathProtoFuncPowEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_get_by_id_proto_list_full
+_cti_op_put_by_id_transition_realloc
+_cti_timeout_check
+__ZN3JSC14TimeoutChecker10didTimeOutEPNS_9ExecStateE
+_cti_op_mul
+__ZN3JSC4Yarr23RegexPatternConstructor25atomBuiltInCharacterClassENS0_23BuiltInCharacterClassIDEb
+_cti_op_convert_this
+__ZNK3JSC8JSString12toThisObjectEPNS_9ExecStateE
+__ZN3JSC12StringObjectC1EN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS_8JSStringE
+__ZN3JSCL22stringProtoFuncReplaceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue12toThisObjectEPNS_9ExecStateE
+__ZNK3JSC8JSObject8toStringEPNS_9ExecStateE
+__ZNK3JSC8JSObject11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZNK3JSC8JSObject12defaultValueEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
+__ZN3JSCL23stringProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12StringObject9classInfoEv
+__ZN7WebCore10StringImpl4costEv
+__ZN3JSC6JSCell11getCallDataERNS_8CallDataE
+__ZN3JSC24charCodeAtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSCL14stringCharLoadERNS_19SpecializedThunkJITE
+_cti_op_get_by_val_string
+_JSValueToBoolean
+_JSValueUnprotect
+_JSGlobalContextRelease
+__ZN3JSC4Heap17collectAllGarbageEv
+__ZN3JSC4Heap9markRootsEv
+__ZN3JSC4Heap30markStackObjectsConservativelyERNS_9MarkStackE
+__ZN3JSC4Heap31markCurrentThreadConservativelyERNS_9MarkStackE
+__ZN3JSC4Heap39markCurrentThreadConservativelyInternalERNS_9MarkStackE
+__ZN3JSC4Heap18markConservativelyERNS_9MarkStackEPvS3_
+__ZN3JSC9MarkStack12markChildrenEPNS_6JSCellE
+__ZN3JSC8JSObject12markChildrenERNS_9MarkStackE
+__ZN3JSC14JSGlobalObject12markChildrenERNS_9MarkStackE
+__ZN3JSCL12markIfNeededERNS_9MarkStackENS_7JSValueE
+__ZN3JSC10JSFunction12markChildrenERNS_9MarkStackE
+__ZN3JSC18FunctionExecutable13markAggregateERNS_9MarkStackE
+__ZN3JSC12JSActivation12markChildrenERNS_9MarkStackE
+__ZN3JSC15JSWrapperObject12markChildrenERNS_9MarkStackE
+__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
+__ZN3JSC18GlobalEvalFunction12markChildrenERNS_9MarkStackE
+__ZN3JSC9CodeBlock13markAggregateERNS_9MarkStackE
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE12markChildrenERNS_9MarkStackE
+__ZN3JSC19JSStaticScopeObject12markChildrenERNS_9MarkStackE
+__ZN3JSC9MarkStack12releaseStackEPvm
+__ZN3JSC4Heap20markProtectedObjectsERNS_9MarkStackE
+__ZN3JSC12SmallStrings12markChildrenERNS_9MarkStackE
+__ZN3JSC9MarkStack7compactEv
+__ZN3JSC4Heap5sweepEv
+__ZN3JSC12DateInstanceD1Ev
 __ZN3JSC9CodeBlock13unlinkCallersEv
 __ZN3JSC9CodeBlock13unlinkCallersEv
-__ZN3WTF6VectorINS_6RefPtrIN3JSC6RegExpEEELm0EE6shrinkEm
+__ZN3JSC8JSObjectD1Ev
 __ZN3JSC12JSActivationD1Ev
 __ZN3JSC12JSActivationD2Ev
 __ZN3JSC12JSActivationD1Ev
 __ZN3JSC12JSActivationD2Ev
-__ZN3JSC12RegExpObjectD1Ev
-__ZN3JSC18RegExpMatchesArrayD1Ev
-__ZN3JSC4Heap5sweepILNS_8HeapTypeE1EEEmv
-__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3WTF17TCMalloc_PageHeap3NewEm
-__ZN3JSC8JITStubs28cti_op_construct_JSConstructEPPv
-__ZN3JSC8JSObject17createInheritorIDEv
-__ZNK3JSC19BracketAccessorNode10isLocationEv
-__ZNK3JSC19BracketAccessorNode21isBracketAccessorNodeEv
-__ZN3JSC17AssignBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator12emitPutByValEPNS_10RegisterIDES2_S2_
-__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
-__ZN3JSC8JITStubs23cti_op_put_by_val_arrayEPPv
-__ZN3JSC8JITStubs13cti_op_strcatEPPv
-__ZN3JSC7UString3Rep15reserveCapacityEi
-__ZN3JSC7UString13appendNumericEi
-__ZN3JSC11concatenateEPNS_7UString3RepEi
-__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC12JSActivation14isDynamicScopeEv
+__ZN3JSC12StringObjectD1Ev
+__ZN3JSC4Heap12resizeBlocksEv
+__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm8EE14expandCapacityEm
+__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE14expandCapacityEmPKS4_
+__ZN3WTF6VectorIPNS0_IN3JSC10RegisterIDELm32EEELm32EE15reserveCapacityEm
+__ZN3JSC8VoidNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE15parseQuantifierEbjj
+__ZN3JSC4Yarr14RegexGenerator19TermGenerationState15jumpToBacktrackERNS_22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpListEP
+__ZN3JSC4Yarr14wordcharCreateEv
+__ZN3JSC4Yarr12digitsCreateEv
+__ZN3JSC4Yarr14RegexGenerator30generatePatternCharacterGreedyERNS1_19TermGenerationStateE
 __ZN3WTF6VectorINS_6RefPtrIN3JSC10RegisterIDEEELm16EE14expandCapacityEm
 __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
-__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
+___initializeScavenger_block_invoke_1
+__Z22TCMalloc_SystemReleasePvm
+__Z21TCMalloc_SystemCommitPvm
+__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
+__ZN3JSCL19mathProtoFuncRandomEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
+__ZN3JSCL23numberProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17NumberConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSCL25numberConstructorMaxValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC18sqrtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSC3JIT26privateCompileGetByIdProtoEPNS_17StructureStubInfoEPNS_9StructureES4_RKNS_10IdentifierERKNS_12PropertySlotEmNS_16
+__ZN3JSC8JSObject3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC10Identifier4fromEPNS_9ExecStateEj
+__ZN3JSC4Yarr13newlineCreateEv
+__ZN3JSC4Yarr14RegexGenerator29generateAssertionWordBoundaryERNS1_19TermGenerationStateE
+__ZN3JSC4Yarr14RegexGenerator22matchAssertionWordcharERNS1_19TermGenerationStateERNS_22AbstractMacroAssemblerINS_12X86Assembler
+__ZN3JSCL26stringProtoFuncToLowerCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL22stringProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7UString4findERKS0_j
+__ZN3JSC17RegExpConstructor18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC17RegExpConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC15constructRegExpEPNS_9ExecStateERKNS_7ArgListE
+__ZNK3JSC6JSCell9classInfoEv
+__ZN3JSCL19regExpProtoFuncExecEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12RegExpObject4execEPNS_9ExecStateERKNS_7ArgListE
+__ZNK3JSC17RegExpConstructor14arrayOfMatchesEPNS_9ExecStateE
+__ZN3JSC18RegExpMatchesArrayC2EPNS_9ExecStateEPNS_24RegExpConstructorPrivateE
+__ZN3JSC7JSArrayC2EN3WTF17NonNullPassRefPtrINS_9StructureEEEj
+__ZN3JSC7JSArray15setSubclassDataEPv
+__ZN3JSCL24regExpConstructorDollar1EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZNK3JSC17RegExpConstructor10getBackrefEPNS_9ExecStateEj
+__ZN3JSC20globalFuncParseFloatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_put_by_id_generic
+__ZN3JSC17BytecodeGenerator29uncheckedRegisterForArgumentsEv
 __ZN3JSC3JIT22emit_op_init_argumentsEPNS_11InstructionE
 __ZN3JSC3JIT24emit_op_create_argumentsEPNS_11InstructionE
 __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
-__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
-__ZN3JSC8JITStubs16cti_op_is_stringEPPv
-__ZN3JSC8JITStubs19cti_op_convert_thisEPPv
-__ZNK3JSC8JSString12toThisObjectEPNS_9ExecStateE
-__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
+__ZN3JSC20MacroAssemblerX86_6413branchTestPtrENS_23MacroAssemblerX86Common9ConditionENS_22AbstractMacroAssemblerINS_12X86Assemb
+_cti_op_load_varargs
+__ZN3JSC3JIT19patchPutByIdReplaceEPNS_9CodeBlockEPNS_17StructureStubInfoEPNS_9StructureEmNS_16ReturnAddressPtrE
+__ZN3JSC21ThrowableBinaryOpNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSCL20stringProtoFuncSplitEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_in
 __ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL19arrayProtoFuncShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL11getPropertyEPNS_9ExecStateEPNS_8JSObjectEj
+__ZNK3JSC7JSValue8toUInt32EPNS_9ExecStateE
+__ZN3JSC7JSArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateEj
 __ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC7JSArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC7JSArray9setLengthEj
 __ZN3JSC7JSArray9setLengthEj
-__ZN3JSC7UString6appendEPKc
-__ZN3JSC8JITStubs23cti_op_create_argumentsEPPv
+__ZN3JSC23CallFunctionCallDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator25emitJumpIfNotFunctionCallEPNS_10RegisterIDEPNS_5LabelE
+_cti_op_create_arguments
+__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC3JIT30privateCompileGetByIdProtoListEPNS_17StructureStubInfoEPNS_30PolymorphicAccessStructureListEiPNS_9StructureES6_RK
+__ZN3JSC9ForInNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator20emitGetPropertyNamesEPNS_10RegisterIDES2_S2_S2_PNS_5LabelE
+__ZN3WTF6VectorIN3JSC12ForInContextELm0EE15reserveCapacityEm
+__ZN3JSC17BytecodeGenerator20emitNextPropertyNameEPNS_10RegisterIDES2_S2_S2_S2_PNS_5LabelE
+__ZN3JSC3JIT18emit_op_get_pnamesEPNS_11InstructionE
+__ZN3JSC3JIT20emit_op_get_by_pnameEPNS_11InstructionE
+__ZN3JSC3JIT22compileGetDirectOffsetENS_12X86Registers10RegisterIDES2_S2_S2_S2_
+__ZN3JSC3JIT18emit_op_next_pnameEPNS_11InstructionE
+__ZN3JSC3JIT24emitSlow_op_get_by_pnameEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_get_pnames
+__ZN3JSC22JSPropertyNameIterator6createEPNS_9ExecStateEPNS_8JSObjectE
+__ZN3JSC8JSObject16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC8JSObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC9Structure16getPropertyNamesERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSCL29objectProtoFuncHasOwnPropertyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject14hasOwnPropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+_cti_op_typeof
+__ZN3JSC20jsTypeStringForValueEPNS_9ExecStateENS_7JSValueE
+__ZN3JSC9Structure27despecifyFunctionTransitionEPS0_RKNS_10IdentifierE
+_cti_has_property
+__ZN3JSC3JIT26emit_op_tear_off_argumentsEPNS_11InstructionE
 __ZN3JSCL19arrayProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __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
+__ZN3JSCL11getPropertyEPNS_9ExecStateEPNS_8JSObjectEj
+__ZN3JSC9Arguments18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+_cti_op_tear_off_arguments
+__ZN3JSC10JSFunction19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZNK3JSC10JSFunction9classInfoEv
+__ZN3JSC17DeleteBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator15emitDeleteByValEPNS_10RegisterIDES2_S2_
 __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC8JSObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC7UString4fromEd
-__ZN3WTF4dtoaEPcdiPiS1_PS0_
-__ZN3JSC8JITStubs21cti_op_put_by_id_failEPPv
-__ZN3JSC13DeleteDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14emitDeleteByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3JSC13DeleteDotNodeD0Ev
-__ZN3JSC3JIT17emit_op_del_by_idEPNS_11InstructionE
-__ZN3JSC8JITStubs16cti_op_del_by_idEPPv
-__ZN3JSC10JSFunction14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+_cti_op_del_by_val
 __ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
 __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
-__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC8JITStubs32cti_op_get_by_id_proto_list_fullEPPv
-__ZN3JSC14InstanceOfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator14emitInstanceOfEPNS_10RegisterIDES2_S2_S2_
-__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_7JSValueERKNS_7ArgListE
-__ZN3JSC12RegExpObject5matchEPNS_9ExecStateERKNS_7ArgListE
-__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_E6rehashEi
-__ZN3WTF6VectorIN3JSC10IdentifierELm20EE14expandCapacityEm
-__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
+_cti_op_is_boolean
+__ZN3JSC10SwitchNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC13CaseBlockNode20emitBytecodeForBlockERNS_17BytecodeGeneratorEPNS_10RegisterIDES4_
+__ZN3JSC13CaseBlockNode18tryOptimizedSwitchERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERiS7_
+__ZN3JSCL17processClauseListEPNS_14ClauseListNodeERN3WTF6VectorIPNS_14ExpressionNodeELm8EEERNS_10SwitchKindERbRiSB_
+__ZN3JSC17BytecodeGenerator11beginSwitchEPNS_10RegisterIDENS_10SwitchInfo10SwitchTypeE
+__ZN3WTF6VectorIN3JSC10SwitchInfoELm0EE14expandCapacityEm
+__ZN3JSC17BytecodeGenerator9endSwitchEjPN3WTF6RefPtrINS_5LabelEEEPPNS_14ExpressionNodeEPS3_ii
+__ZN3WTF6VectorIN3JSC15SimpleJumpTableELm0EE14expandCapacityEm
+__ZNK3JSC5Label4bindEii
+__ZN3JSC3JIT18emit_op_switch_immEPNS_11InstructionE
+__ZN3WTF6VectorIN3JSC12SwitchRecordELm0EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC17CodeLocationLabelELm0EE4growEm
+_cti_op_switch_imm
 __ZN3JSC4Yarr23RegexPatternConstructor8copyTermERNS0_11PatternTermE
 __ZN3JSC4Yarr23RegexPatternConstructor8copyTermERNS0_11PatternTermE
-__ZL17bracketIsAnchoredPKh
+__ZL14compileBracketiPiPPhPPKtS3_P9ErrorCodeiS_S_R11CompileData
 __ZL32branchFindFirstAssertedCharacterPKhb
 __ZL20branchNeedsLineStartPKhjj
 __ZL32branchFindFirstAssertedCharacterPKhb
 __ZL20branchNeedsLineStartPKhjj
+__ZL17bracketIsAnchoredPKh
+_cti_op_get_by_id_array_fail
+__ZN3JSC17PropertyNameArray3addEPN7WebCore10StringImplE
+__ZN3WTF7HashSetIPN7WebCore10StringImplENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN7WebCore10StringImplES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3WTF6VectorIN3JSC10IdentifierELm20EE14expandCapacityEm
+__ZN3JSCL28numberConstructorPosInfinityEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL28numberConstructorNegInfinityEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC4Heap5resetEv
+__ZN3JSC9Arguments12markChildrenERNS_9MarkStackE
+__ZN3JSC22JSPropertyNameIterator12markChildrenERNS_9MarkStackE
+__ZN3JSC3JIT10unlinkCallEPNS_12CallLinkInfoE
+__ZN3JSC9LabelNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC12RegExpObjectD1Ev
+__ZN3JSC18RegExpMatchesArrayD1Ev
+__ZNK3JSC7JSArray12subclassDataEv
+__ZN3JSC15ObjectPrototype18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC22JSPropertyNameIteratorD1Ev
+__ZN3JSC22JSPropertyNameIteratorD2Ev
+__ZNK3JSC7JSArray9classInfoEv
+__ZN3JSC7JSArray15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
+__ZN3JSC9ArgumentsD1Ev
+__ZN3JSC9ArgumentsD2Ev
+__ZN3JSC7UString4fromEd
+__ZN3WTF32doubleToStringInJavaScriptFormatEdPcPj
+__ZN3WTF4dtoaEPcdiPiS1_PS0_
+__ZN3JSC10Identifier11addSlowCaseEPNS_12JSGlobalDataEPN7WebCore10StringImplE
+__ZN3WTF6VectorIPN3JSC9StructureELm8EE14expandCapacityEm
+_cti_op_resolve_base
+__ZN3JSC12JSActivation18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC20charAtThunkGeneratorEPNS_12JSGlobalDataEPNS_14ExecutablePoolE
+__ZN3JSCL21stringProtoFuncCharAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC14PostfixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator11emitPostIncEPNS_10RegisterIDES2_
+__ZN3JSC3JIT16emit_op_post_incEPNS_11InstructionE
+__ZN3JSC3JIT20emitSlow_op_post_incEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC18PostfixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator18pushFinallyContextEPNS_5LabelEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator17popFinallyContextEv
+__ZN3JSC17BytecodeGenerator19highestUsedRegisterEv
+__ZN3JSC17BytecodeGenerator18emitJumpSubroutineEPNS_10RegisterIDEPNS_5LabelE
+__ZN3JSC17BytecodeGenerator20emitSubroutineReturnEPNS_10RegisterIDE
+__ZN3JSC3JIT11emit_op_jsrEPNS_11InstructionE
+__ZN3WTF6VectorIN3JSC3JIT7JSRInfoELm0EE14expandCapacityEm
+__ZN3JSC3JIT13emit_op_throwEPNS_11InstructionE
+__ZN3JSC3JIT12emit_op_sretEPNS_11InstructionE
+__ZN3JSC21ReadModifyBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+_cti_op_lesseq
+__ZN3JSCL20stringProtoFuncMatchEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC18RegExpMatchesArray17fillArrayInstanceEPNS_9ExecStateE
+__ZN3JSC14jsReplaceRangeEPNS_9ExecStateERKNS_7UStringEiiS4_
 __ZN3JSC18RegExpMatchesArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __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
+__ZNK3JSC8JSObject11hasPropertyEPNS_9ExecStateEj
+__ZN3JSCL24stringProtoFuncSubstringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_create_arguments_no_params
+__ZN3JSCL21arrayProtoFuncUnShiftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_pre_dec
+_cti_op_is_undefined
+__ZN3JSC13DeleteDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitDeleteByIdEPNS_10RegisterIDES2_RKNS_10IdentifierE
 __ZN3JSC23FunctionCallBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC23FunctionCallBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC3JIT17emit_op_del_by_idEPNS_11InstructionE
+_cti_op_del_by_id
+__ZN3WTF37parseDateFromNullTerminatedCharactersEPKc
+__ZN3WTFL37parseDateFromNullTerminatedCharactersEPKcRbRi
+_cti_op_get_by_id_proto_fail
+__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
+__ZN3WTF6VectorItLm64EE15reserveCapacityEm
 __ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC20EvalFunctionCallNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17BytecodeGenerator19emitResolveWithBaseEPNS_10RegisterIDES2_RKNS_10IdentifierE
-__ZN3JSC23FunctionCallBracketNodeD0Ev
-__ZN3JSC20EvalFunctionCallNodeD0Ev
-__ZN3JSC3JIT25emit_op_resolve_with_baseEPNS_11InstructionE
+__ZN3JSC17BytecodeGenerator12emitCallEvalEPNS_10RegisterIDES2_S2_PNS_13ArgumentsNodeEjjj
 __ZN3JSC3JIT17emit_op_call_evalEPNS_11InstructionE
 __ZN3JSC3JIT21emitSlow_op_call_evalEPNS_11InstructionERPNS_13SlowCaseEntryE
 __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
+_cti_op_resolve
+_cti_op_call_eval
 __ZN3JSC11Interpreter8callEvalEPNS_9ExecStateEPNS_12RegisterFileEPNS_8RegisterEiiRNS_7JSValueE
 __ZN3JSC13LiteralParser5Lexer3lexERNS1_18LiteralParserTokenE
 __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
+__ZN3JSC13LiteralParser5parseENS0_11ParserStateE
+__ZN3JSC14EvalExecutable7compileEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3JSC6Parser5parseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPNS_8DebuggerEPNS_9ExecStateERKNS_10SourceCodeEPi
+__ZN3JSC8EvalNode6createEPNS_12JSGlobalDataEPNS_14SourceElementsEPN3WTF6VectorISt4pairIPKNS_10IdentifierEjELm0EEEPNS6_IPNS_16Fu
+__ZNK3JSC10ScopeChain10localDepthEv
+__ZNK3JSC12JSActivation9classInfoEv
+__ZN3JSC17BytecodeGeneratorC1EPNS_8EvalNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrIN7WebCore10StringImplEE
+__ZN3JSC17BytecodeGeneratorC2EPNS_8EvalNodeEPKNS_8DebuggerERKNS_10ScopeChainEPN3WTF7HashMapINS9_6RefPtrIN7WebCore10StringImplEE
 __ZN3JSC8EvalNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZThn16_N3JSC8EvalNodeD0Ev
 __ZN3JSC8EvalNodeD0Ev
 __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
+__ZN3WTF9HashTableINS_6RefPtrIN7WebCore10StringImplEEESt4pairIS4_NS1_IN3JSC14EvalExecutableEEEENS_18PairFirstExtractorIS9_EENS2
+__ZN3JSC9ExecState9thisValueEv
+__ZN3JSC11Interpreter7executeEPNS_14EvalExecutableEPNS_9ExecStateEPNS_8JSObjectEiPNS_14ScopeChainNodeEPNS_7JSValueE
+__ZN3JSC14EvalExecutable15generateJITCodeEPNS_9ExecStateEPNS_14ScopeChainNodeE
+__ZN3JSC9ThrowNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+_cti_op_throw
+__ZN3JSC9CodeBlock34reparseForExceptionInfoIfNecessaryEPNS_9ExecStateE
+__ZN3JSC18FunctionExecutable20reparseExceptionInfoEPNS_12JSGlobalDataEPNS_14ScopeChainNodeEPNS_9CodeBlockE
+__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_7JSValueEjb
+__ZN3JSC9CodeBlock24handlerForBytecodeOffsetEj
+__ZN3JSC11Interpreter15unwindCallFrameERPNS_9ExecStateENS_7JSValueERjRPNS_9CodeBlockE
+__ZN3JSC9CodeBlock36hasGlobalResolveInfoAtBytecodeOffsetEj
+_cti_op_push_new_scope
+__ZN3WTF7HashMapINS_6RefPtrIN7WebCore10StringImplEEEN3JSC16SymbolTableEntryENS5_17IdentifierRepHashENS_10HashTraitsIS4_EENS5_26
+__ZN3JSC19JSStaticScopeObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC12JSActivation3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+_cti_op_pop_scope
+_cti_op_is_number
+__ZN3JSCL20arrayProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_stricteq
+__ZN3JSCL20arrayProtoFuncSpliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
+__ZN3JSC9CodeBlock27lineNumberForBytecodeOffsetEPNS_9ExecStateEj
+__ZN3JSC8RopeImpl20destructNonRecursiveEv
+__ZN3JSC8RopeImpl23derefFibersNonRecursiveERN3WTF6VectorIPS0_Lm32EEE
+__ZN3JSCL17arrayProtoFuncPopEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray3popEv
+__ZN7WebCore6String6numberEd
+__ZN3JSC10Identifier5equalEPKN7WebCore10StringImplEPKc
+__ZNK3JSC9Arguments9classInfoEv
+__ZN3JSC9Arguments15copyToRegistersEPNS_9ExecStateEPNS_8RegisterEj
+__ZN3JSC14InstanceOfNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator14emitInstanceOfEPNS_10RegisterIDES2_S2_S2_
+__ZN3JSC3JIT18emit_op_instanceofEPNS_11InstructionE
+__ZN3JSC3JIT22emitSlow_op_instanceofEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC17BytecodeGenerator11emitPostDecEPNS_10RegisterIDES2_
+__ZN3JSC3JIT16emit_op_post_decEPNS_11InstructionE
+__ZN3JSC3JIT20emitSlow_op_post_decEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_less
+__ZN3JSC13PrefixDotNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+_cti_op_call_NotJSFunction
+__ZN3JSC17StringConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callStringConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSString8toNumberEPNS_9ExecStateE
+__ZNK3JSC7UString8toDoubleEv
+__ZN3JSC18BooleanConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL22callBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC9ExecState10arrayTableEPS0_
+__ZN3JSC17DeleteResolveNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSCL18arrayProtoFuncSortEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray4sortEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE
+__ZN3WTF6VectorIN3JSC26AVLTreeNodeForArrayCompareELm0EE14expandCapacityEm
+__ZN3JSC11Interpreter20prepareForRepeatCallEPNS_18FunctionExecutableEPNS_9ExecStateEPNS_10JSFunctionEiPNS_14ScopeChainNodeEPNS_
+__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE6insertEi
+__ZN3JSC11Interpreter7executeERNS_16CallFrameClosureEPNS_7JSValueE
+__ZN3WTF7AVLTreeIN3JSC32AVLTreeAbstractorForArrayCompareELj44ENS_18AVLTreeDefaultBSetILj44EEEE7balanceEi
+__ZN3JSC11Interpreter13endRepeatCallERNS_16CallFrameClosureE
+__ZN3JSCL16mathProtoFuncExpEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL17mathProtoFuncATanEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZL17makeLeftShiftNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
+__ZN3JSC3JIT14emit_op_lshiftEPNS_11InstructionE
+__ZN3JSC3JIT14emit_op_bitandEPNS_11InstructionE
+__ZN3JSC3JIT14emit_op_rshiftEPNS_11InstructionE
+__ZN3JSC3JIT18emitSlow_op_lshiftEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT18emitSlow_op_bitandEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC3JIT18emitSlow_op_rshiftEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC32jsSpliceSubstringsWithSeparatorsEPNS_9ExecStateEPNS_8JSStringERKNS_7UStringEPKNS_11StringRangeEiPS5_i
+__ZN3JSCL26stringProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue20toIntegerPreserveNaNEPNS_9ExecStateE
+__ZNK3JSC7UString5rfindERKS0_j
+__ZN3WTF6VectorIiLm0EE15reserveCapacityEm
+__ZN3WTF6VectorINS_6RefPtrIN3JSC5LabelEEELm8EE15reserveCapacityEm
+__ZN3WTF6VectorISt4pairIiiELm8EE14expandCapacityEm
+__ZN3JSC11DoWhileNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC3JIT19emit_op_switch_charEPNS_11InstructionE
+_cti_op_switch_char
+__ZN3JSCL21stringProtoFuncSearchEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF10RefCountedIN3JSC6RegExpEE5derefEv
+__ZN3JSC14JSGlobalObjectD2Ev
+__ZN3JSC12RegisterFile17clearGlobalObjectEPNS_14JSGlobalObjectE
+__ZN3JSC17FunctionPrototypeD1Ev
+__ZN3JSC15ObjectPrototypeD1Ev
+__ZN3JSC14ArrayPrototypeD1Ev
+__ZN3JSC15StringPrototypeD1Ev
+__ZN3JSC16BooleanPrototypeD1Ev
+__ZN3JSC15NumberPrototypeD1Ev
+__ZN3JSC13DatePrototypeD1Ev
+__ZN3JSC15RegExpPrototypeD1Ev
+__ZN3JSC14ErrorPrototypeD1Ev
+__ZN3JSC20NativeErrorPrototypeD1Ev
+__ZN3JSC17ObjectConstructorD1Ev
+__ZN3JSC19FunctionConstructorD1Ev
+__ZN3JSC16ArrayConstructorD1Ev
+__ZN3JSC17StringConstructorD1Ev
+__ZN3JSC18BooleanConstructorD1Ev
+__ZN3JSC17NumberConstructorD1Ev
+__ZN3JSC15DateConstructorD1Ev
+__ZN3JSC17RegExpConstructorD1Ev
+__ZN3JSC16ErrorConstructorD1Ev
+__ZN3JSC22NativeErrorConstructorD1Ev
+__ZN3JSC10MathObjectD1Ev
+__ZN3JSC10JSONObjectD1Ev
+__ZN3JSC18GlobalEvalFunctionD1Ev
+__ZN3JSC19JSStaticScopeObjectD1Ev
+__ZN3JSC19JSStaticScopeObjectD2Ev
+__ZN3WTF6VectorIPvLm0EE14expandCapacityEmPKS1_
+__ZN3WTF6VectorIPvLm0EE15reserveCapacityEm
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEED1Ev
+__ZL25clearReferenceToPrototypeP13OpaqueJSValue
+_JSObjectGetPrivate
+__ZNK3JSC16JSCallbackObjectINS_8JSObjectEE9classInfoEv
+__ZN3JSC28globalFuncEncodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL6encodeEPNS_9ExecStateERKNS_7ArgListEPKc
+__ZN3WTF6VectorItLm64EE9tryAppendItEEbPKT_m
+__ZN3WTF6VectorItLm64EE18tryReserveCapacityEm
+__ZN3JSC28globalFuncDecodeURIComponentEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL6decodeEPNS_9ExecStateERKNS_7ArgListEPKcb
+__ZN3WTF7Unicode18UTF8SequenceLengthEc
+__ZN3WTF7Unicode18decodeUTF8SequenceEPKc
+__ZN3JSC18EmptyStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSCltERKNS_7UStringES2_
+__ZN3WTF6VectorItLm0EE14expandCapacityEmPKt
+__ZN3WTF6VectorItLm0EE15reserveCapacityEm
+__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateEjNS_7JSValueE
+__ZN3JSC18RegExpMatchesArray14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC18RegExpMatchesArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC14EvalExecutableD0Ev
+__ZN3JSC13EvalCodeBlockD0Ev
+__ZN3JSC3JIT30emit_op_resolve_global_dynamicEPNS_11InstructionE
+__ZN3JSC3JIT34emitSlow_op_resolve_global_dynamicEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSC19FunctionConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL32constructWithFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC17constructFunctionEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC3JIT18emit_op_jmp_scopesEPNS_11InstructionE
+__ZN3JSC8WithNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC17BytecodeGenerator13emitPushScopeEPNS_10RegisterIDE
+__ZN3JSC3JIT18emit_op_push_scopeEPNS_11InstructionE
+_cti_op_push_scope
+_cti_op_jmp_scopes
+__ZN3WTF6VectorIN3JSC14ExecutablePool10AllocationELm2EE14expandCapacityEm
+__ZN3JSCL26stringProtoFuncToUpperCaseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21arrayProtoFuncIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16mathProtoFuncCosEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL17mathProtoFuncASinEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_loop_if_lesseq
+__ZN3JSC7JSArray4sortEPNS_9ExecStateE
+__ZN3JSC7JSArray17compactForSortingEv
+__ZL18makeRightShiftNodePN3JSC12JSGlobalDataEPNS_14ExpressionNodeES3_b
+__ZN3JSC3JIT13emit_op_bitorEPNS_11InstructionE
+__ZN3JSC3JIT17emitSlow_op_bitorEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3WTF6VectorIN3JSC11StringRangeELm16EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC7UStringELm16EE14expandCapacityEmPKS2_
+__ZN3WTF6VectorIN3JSC7UStringELm16EE15reserveCapacityEm
+__ZNK3JSC8JSString8toObjectEPNS_9ExecStateE
+__ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+_cti_op_post_dec
+__ZN3JSC3JIT14emit_op_bitxorEPNS_11InstructionE
+__ZN3JSC3JIT18emitSlow_op_bitxorEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_bitand
+_cti_op_bitor
+__ZN7WebCore10StringImpl18simplifyWhiteSpaceEv
+_cti_op_is_object
+__ZN3JSC14jsIsObjectTypeENS_7JSValueE
+__ZN3JSC17PrototypeFunction11getCallDataERNS_8CallDataE
+__ZN3JSC14globalFuncEvalEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL19isNonASCIIIdentPartEi
+__ZN3JSC11Interpreter7executeEPNS_14EvalExecutableEPNS_9ExecStateEPNS_8JSObjectEPNS_14ScopeChainNodeEPNS_7JSValueE
+_cti_op_mod
+__ZN7WebCore6String6appendEc
+__ZN7WebCore6String6appendEPKtj
+__ZN3JSC16globalFuncEscapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK7WebCore6String8foldCaseEv
+__ZN7WebCore10StringImpl8foldCaseEv
+__ZN3JSC10JSFunction15argumentsGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZNK3JSC11Interpreter17retrieveArgumentsEPNS_9ExecStateEPNS_10JSFunctionE
+__ZN3WTF6VectorIPN3JSC14ExpressionNodeELm16EE14expandCapacityEm
+__ZN3WTF6VectorINS_6RefPtrIN3JSC10RegisterIDEEELm16EE15reserveCapacityEm
+__ZN3WTF6VectorIN7WebCore6StringELm0EE14expandCapacityEm
+__ZN3JSC8JSObject14deletePropertyEPNS_9ExecStateEj
+__ZN3JSC18globalFuncUnescapeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorItLm64EE14expandCapacityEm
+__ZN3JSC3JIT16emit_op_jeq_nullEPNS_11InstructionE
+__ZN3WTF7CStringC1EPKc
+__ZN3WTFeqERKNS_7CStringES2_
+__ZN7WebCore17equalIgnoringCaseEPKtPKcj
+__ZNK7WebCore6String6toUIntEPb
+__ZN7WebCore10StringImpl6toUIntEPb
+__ZN7WebCore16charactersToUIntEPKtmPb
+__ZN7WebCore10StringImpl11reverseFindEti
+__ZN3WTF23waitForThreadCompletionEjPPv
+__ZN3WTF14FastMallocZone10statisticsEP14_malloc_zone_tP19malloc_statistics_t
+__ZNK7WebCore6String18simplifyWhiteSpaceEv
+__ZN7WebCore10StringImpl23defaultWritingDirectionEv
+__ZN3JSCL20dateProtoFuncSetTimeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL21dateProtoFuncGetMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12DateInstance26calculateGregorianDateTimeEPNS_9ExecStateE
+__ZN3JSC21msToGregorianDateTimeEPNS_9ExecStateEdbRNS_17GregorianDateTimeE
+__ZN3WTFL18calculateDSTOffsetEdd
+__ZN3JSCL20dateProtoFuncGetDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue8inheritsEPKNS_9ClassInfoE
+__ZN3JSCL20dateProtoFuncGetYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL21dateProtoFuncGetHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL23dateProtoFuncGetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC3JIT17emit_op_jneq_nullEPNS_11InstructionE
+__ZN3JSCL20dateProtoFuncSetYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7JSValue7toInt32EPNS_9ExecStateERb
+__ZN3JSC21gregorianDateTimeToMSEPNS_9ExecStateERKNS_17GregorianDateTimeEdb
+__ZN3WTF18dateToDaysFrom1970Eiii
+__ZN3JSCL21dateProtoFuncSetMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23setNewValueFromDateArgsEPNS_9ExecStateENS_7JSValueERKNS_7ArgListEib
+__ZN3JSCL20dateProtoFuncSetDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncToGMTStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12DateInstance29calculateGregorianDateTimeUTCEPNS_9ExecStateE
+__ZN3JSC20formatDateUTCVariantERKNS_17GregorianDateTimeERA100_c
+__ZN3JSC13formatTimeUTCERKNS_17GregorianDateTimeERA100_c
+__ZN3JSC13tryMakeStringIPcPKcS1_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_
+__ZN3JSC9parseDateEPNS_9ExecStateERKNS_7UStringE
+__ZN3JSC37parseDateFromNullTerminatedCharactersEPNS_9ExecStateEPKc
+__ZN3JSC16ArrayConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL29constructWithArrayConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSCL27constructArrayWithSizeQuirkEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEEj
+__ZN3JSC17StringConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithStringConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC12StringObjectC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7UStringE
+__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7UStringE
+_cti_op_pre_inc
 __ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL23dateProtoFuncGetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL19dateProtoFuncGetDayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN7WebCore6String6removeEji
+__ZN3JSC23MacroAssemblerX86Common12branchTest32ENS0_9ConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_5Imm
+__ZN3JSC23MacroAssemblerX86Common8branch32ENS0_9ConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE7AddressENS4_5Imm32E
+__ZN3JSC12X86Assembler23X86InstructionFormatter9twoByteOpENS0_15TwoByteOpcodeIDEiNS_12X86Registers10RegisterIDEi
+__ZNK3JSC7UStringixEj
+__ZN3JSC3JIT19emit_op_to_jsnumberEPNS_11InstructionE
+__ZN3JSC3JIT23emitSlow_op_to_jsnumberEPNS_11InstructionERPNS_13SlowCaseEntryE
+_cti_op_to_jsnumber
 __ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL30dateProtoFuncGetTimezoneOffsetEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierEjPNS_9CodeBlockE
-__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEPNS_9ExecStateEjRiS3_S3_
 __ZN3JSC5Error6createEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEilS6_
 __ZN3JSC22NativeErrorConstructor16getConstructDataERNS_13ConstructDataE
 __ZN3JSC5Error6createEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEilS6_
 __ZN3JSC22NativeErrorConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
 __ZN3JSCL35constructWithNativeErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
 __ZN3JSC22NativeErrorConstructor9constructEPNS_9ExecStateERKNS_7ArgListE
 __ZN3JSCL35constructWithNativeErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
 __ZN3JSC22NativeErrorConstructor9constructEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC13ErrorInstanceC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
 __ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
 __ZN3JSC8JSObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
-__ZN3JSCL23returnToThrowTrampolineEPNS_12JSGlobalDataEPvRS2_
+__ZNK3JSC8JSObject13exceptionTypeEv
+__ZN3JSCL22errorProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC13tryMakeStringINS_7UStringEPKcS1_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_
+__ZN3JSC13ErrorInstanceD1Ev
+__ZN3JSC4Heap9freeBlockEm
+__ZN3JSC4Heap12freeBlockPtrEPNS_14CollectorBlockE
+__ZN3JSC28createUndefinedVariableErrorEPNS_9ExecStateERKNS_10IdentifierEjPNS_9CodeBlockE
+__ZN3JSC9CodeBlock32expressionRangeForBytecodeOffsetEPNS_9ExecStateEjRiS3_S3_
+__ZN3JSC10makeStringIPKcNS_7UStringEEES3_T_T0_
+__ZN3JSC13tryMakeStringIPKcNS_7UStringEEEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_
+__ZN3JSCL23returnToThrowTrampolineEPNS_12JSGlobalDataENS_16ReturnAddressPtrERS2_
 _ctiVMThrowTrampoline
 _ctiVMThrowTrampoline
-__ZN3JSC8JITStubs12cti_vm_throwEPPv
-__ZN3JSC11Interpreter14throwExceptionERPNS_9ExecStateERNS_7JSValueEjb
+_cti_vm_throw
 __ZNK3JSC8JSObject22isNotAnObjectErrorStubEv
 __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
+__ZNK3JSC7UString5asciiEv
+__ZN3JSC6JSLock12DropAllLocksC1ENS_14JSLockBehaviorE
+__ZN3JSCL17createJSLockCountEv
+__ZN3JSC6JSLock12DropAllLocksD1Ev
+__ZNK7WebCore6String5upperEv
+__ZN3JSC4Yarr23RegexPatternConstructor31atomParentheticalAssertionBeginEb
+__ZN3JSC4Yarr14RegexGenerator30generateParentheticalAssertionERNS1_19TermGenerationStateE
+__ZNK3JSC8JSObject8toNumberEPNS_9ExecStateE
+__ZN3WTF6VectorIPN3JSC4Yarr18PatternDisjunctionELm4EE14expandCapacityEmPKS4_
+__ZN3JSCL18regExpObjectSourceEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC17RegExpConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callRegExpConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject9classNameEv
+__ZN3JSC13tryMakeStringIPKcNS_7UStringES2_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_
+__ZN3JSC16JSVariableObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC9Structure27despecifyDictionaryFunctionERKNS_10IdentifierE
+__ZN3JSC36constructBooleanFromImmediateBooleanEPNS_9ExecStateENS_7JSValueE
+__ZN3JSC13BooleanObjectC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC17ObjectConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithObjectConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZNK3JSC9ArrayNode13isSimpleArrayEv
+__ZN3JSC7JSArray14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSCL27compareByStringPairForQSortEPKvS1_
+__ZN3JSC7compareERKNS_7UStringES2_
+__ZN3JSCL24dateProtoFuncToUTCStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC17NumberConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL30constructWithNumberConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC12NumberObjectC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSCL20isNonASCIIIdentStartEi
+__ZN3JSC9Arguments3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC14MacroAssembler4peekENS_12X86Registers10RegisterIDEi
+__ZN3JSC4Yarr14RegexGenerator12atEndOfInputEv
+__ZN3JSC14MacroAssembler8branch32ENS_23MacroAssemblerX86Common9ConditionENS_12X86Registers10RegisterIDENS_22AbstractMacroAssemb
+__ZN3JSC22AbstractMacroAssemblerINS_12X86AssemblerEE8JumpList6linkToENS2_5LabelEPS2_
+__ZN3JSC14MacroAssembler4pokeENS_12X86Registers10RegisterIDEi
+__ZN3JSCL28substituteBackreferencesSlowERKNS_7UStringES2_PKiPNS_6RegExpEj
+__ZN3WTF6VectorItLm0EE6appendItEEvPKT_m
+_cti_op_to_primitive
+__ZN3JSC15constructNumberEPNS_9ExecStateENS_7JSValueE
+__ZNK3JSC12NumberObject9classInfoEv
+__Z12jsRegExpFreeP8JSRegExp
+__ZN3JSC13BooleanObjectD1Ev
+__ZN3JSCL18stringFromCharCodeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10makeStringIPKcNS_7UStringES2_EES3_T_T0_T1_
+__ZN3JSCL19dateProtoFuncGetDayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC14EvalExecutable20reparseExceptionInfoEPNS_12JSGlobalDataEPNS_14ScopeChainNodeEPNS_9CodeBlockE
+__ZN3JSCL22objectProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
+__ZN3JSCL24dateProtoFuncGetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12RegExpObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSCL24setRegExpObjectLastIndexEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
+__Z15jsc_pcre_xclassiPKh
+__ZN3JSCL28regExpConstructorLeftContextEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZNK3JSC17RegExpConstructor14getLeftContextEPNS_9ExecStateE
+_cti_to_object
+__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
+_cti_op_sub
+__ZN3JSC17NumberConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callNumberConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+_cti_op_bitxor
+_cti_op_is_function
+__ZN3JSC16jsIsFunctionTypeENS_7JSValueE
+__ZN3JSC12NumberObjectD1Ev
+__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EE14expandCapacityEm
+__ZN3JSC8JSString18getPrimitiveNumberEPNS_9ExecStateERdRNS_7JSValueE
+__ZN7WebCore6String26fromUTF8WithLatin1FallbackEPKcm
+__ZN7WebCore6String8fromUTF8EPKcm
+__ZN3WTF10fastStrDupEPKc
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
+__ZN3WTF6VectorIN3JSC15StringJumpTableELm0EE14expandCapacityEm
+__ZN3WTF9HashTableINS_6RefPtrIN7WebCore10StringImplEEESt4pairIS4_N3JSC14OffsetLocationEENS_18PairFirstExtractorIS8_EENS2_10Stri
+__ZN3JSC3JIT21emit_op_switch_stringEPNS_11InstructionE
+__ZN3JSC13LiteralParser5Lexer9lexNumberERNS1_18LiteralParserTokenE
+__ZN3WTF6VectorIPNS_14StringImplBaseELm32EE14expandCapacityEm
+__ZN3JSC4Yarr17nonwordcharCreateEv
+__ZN3JSC3JIT15emit_op_eq_nullEPNS_11InstructionE
+_cti_op_switch_string
+__ZN3JSC12X86Assembler23X86InstructionFormatter15emitRexIfNeededEiii
+__ZN3JSC12X86Assembler23X86InstructionFormatter11memoryModRMEiNS_12X86Registers10RegisterIDES3_ii
+__ZN3JSC4Yarr6ParserINS0_23RegexPatternConstructorEE28CharacterClassParserDelegate25atomBuiltInCharacterClassENS0_23BuiltInChar
+__ZN3JSC4Yarr15nonspacesCreateEv
+__ZN3JSCL25functionProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC21UStringSourceProvider8getRangeEii
+__ZNK3JSC7UString6substrEjj
+__ZN3JSC10makeStringINS_7UStringEPKcS1_EES1_T_T0_T1_
+__ZNK3JSC18FunctionExecutable11paramStringEv
+__ZN3WTF6VectorItLm64EE6appendItEEvPKT_m
+__ZN3JSC13tryMakeStringIPKcNS_7UStringES2_S3_S2_S3_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_T2_T3_T4_
+__ZN3JSC17RegExpConstructor3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSCL21arrayProtoFuncForEachEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10JSFunction14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSCL22arrayProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC16ErrorConstructor16getConstructDataERNS_13ConstructDataE
+__ZN3JSCL29constructWithErrorConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
+__ZN3JSC14constructErrorEPNS_9ExecStateERKNS_7ArgListE
+_cti_op_instanceof
+__ZN3JSC6RegExp6createEPNS_12JSGlobalDataERKNS_7UStringE
+__ZN3WTF9HashTableIPN7WebCore10StringImplES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findIS3_NS_
+_cti_op_get_by_id_string_fail
+__ZN3JSCL20stringProtoFuncSliceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC14MacroAssembler4jumpENS_22AbstractMacroAssemblerINS_12X86AssemblerEE5LabelE
+__ZN3JSCL23regExpProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL18regExpObjectGlobalEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL22regExpObjectIgnoreCaseEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL21regExpObjectMultilineEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC13tryMakeStringIPKcNS_7UStringEPcEEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_
+__ZN3JSC12JSActivation14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3WTFL10timerFiredEP16__CFRunLoopTimerPv
+__ZN7WebCore22charactersToUIntStrictEPKtmPbi
+__ZN3WTF9HashTableIjSt4pairIjN3JSC7JSValueEENS_18PairFirstExtractorIS4_EENS_7IntHashIjEENS_14PairHashTraitsINS_10HashTraitsIjEE
+__ZN3JSCL23dateProtoFuncSetMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23setNewValueFromTimeArgsEPNS_9ExecStateENS_7JSValueERKNS_7ArgListEib
+__ZN3JSCL23dateProtoFuncSetSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL28dateProtoFuncSetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL9dateParseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21dateProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10formatDateERKNS_17GregorianDateTimeERA100_c
+__ZN3JSC10formatTimeERKNS_17GregorianDateTimeERA100_c
+__ZN3JSC19globalFuncEncodeURIEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC13UnaryPlusNode14stripUnaryPlusEv
+__ZN3JSCL20arrayProtoFuncFilterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL27objectProtoFuncLookupGetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject12lookupGetterEPNS_9ExecStateERKNS_10IdentifierE
+__ZNK3JSC6JSCell14isGetterSetterEv
+__ZN3JSCL27objectProtoFuncDefineSetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPS0_j
+__ZN3JSCL27objectProtoFuncDefineGetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPS0_j
+__ZNK3JSC12GetterSetter14isGetterSetterEv
+__ZN3JSC8JSObject15unwrappedObjectEv
+__ZN3JSC10JSFunction12callerGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
+__ZN3JSC16toUInt32SlowCaseEdRb
+__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE
+__ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE
+_cti_op_get_by_id_getter_stub
+__ZN3JSC12GetterSetter12markChildrenERNS_9MarkStackE
+__ZN3JSCL17mathProtoFuncACosEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF13tryFastCallocEmm
+__ZN3JSC3JIT20emit_op_resolve_skipEPNS_11InstructionE
+_cti_op_resolve_skip
+__ZN3JSC3JIT15emit_op_urshiftEPNS_11InstructionE
+__ZN3JSC3JIT19emitSlow_op_urshiftEPNS_11InstructionERPNS_13SlowCaseEntryE
+__ZN3JSCL25stringProtoFuncCharCodeAtEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorIcLm0EE14expandCapacityEm
+__ZN3JSC15AssignErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC23ThrowableExpressionData14emitThrowErrorERNS_17BytecodeGeneratorENS_9ErrorTypeEPKc
+__ZN3JSC17BytecodeGenerator12emitNewErrorEPNS_10RegisterIDENS_9ErrorTypeENS_7JSValueE
+__ZN3JSC3JIT17emit_op_new_errorEPNS_11InstructionE
+__ZN3JSCL27objectProtoFuncLookupSetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
 __ZN3JSC26createNotAnObjectErrorStubEPNS_9ExecStateEb
 __ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZNK3JSC22JSNotAnObjectErrorStub22isNotAnObjectErrorStubEv
 __ZN3JSC22createNotAnObjectErrorEPNS_9ExecStateEPNS_22JSNotAnObjectErrorStubEjPNS_9CodeBlockE
 __ZN3JSC9CodeBlock37getByIdExceptionInfoForBytecodeOffsetEPNS_9ExecStateEjRNS_8OpcodeIDE
 __ZN3JSCL18createErrorMessageEPNS_9ExecStateEPNS_9CodeBlockEiiiNS_7JSValueENS_7UStringE
 __ZN3JSC26createNotAnObjectErrorStubEPNS_9ExecStateEb
 __ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZNK3JSC22JSNotAnObjectErrorStub22isNotAnObjectErrorStubEv
 __ZN3JSC22createNotAnObjectErrorEPNS_9ExecStateEPNS_22JSNotAnObjectErrorStubEjPNS_9CodeBlockE
 __ZN3JSC9CodeBlock37getByIdExceptionInfoForBytecodeOffsetEPNS_9ExecStateEjRNS_8OpcodeIDE
 __ZN3JSCL18createErrorMessageEPNS_9ExecStateEPNS_9CodeBlockEiiiNS_7JSValueENS_7UStringE
-__ZN3JSC13ErrorInstanceD1Ev
+__ZN3JSC10makeStringIPKcNS_7UStringES2_S3_S2_S3_S2_EES3_T_T0_T1_T2_T3_T4_T5_
+__ZN3JSC13tryMakeStringIPKcNS_7UStringES2_S3_S2_S3_S2_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_T2_T3_T4_T5_
 __ZN3JSC22JSNotAnObjectErrorStubD1Ev
 __ZN3JSC13JSNotAnObjectD1Ev
 __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
+__ZN3JSC12GetterSetterD1Ev
+__ZN3JSC20FixedVMPoolAllocator17coalesceFreeSpaceEv
+__ZN3WTF6VectorIPN3JSC13FreeListEntryELm0EE15reserveCapacityEm
+__ZN3JSCL35reverseSortFreeListEntriesByPointerEPKvS1_
+__ZN3JSCL33reverseSortCommonSizedAllocationsEPKvS1_
+__ZN7WebCore20equalIgnoringNullityEPNS_10StringImplES1_
+__ZN3JSC19globalFuncDecodeURIEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC16ErrorConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL20callErrorConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL22functionProtoFuncApplyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC9Arguments11fillArgListEPNS_9ExecStateERNS_20MarkedArgumentBufferE
+__ZN3JSCL21functionProtoFuncCallEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10JSONObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+_cti_op_lshift
+__ZN3JSCL29regExpConstructorRightContextEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZNK3JSC17RegExpConstructor15getRightContextEPNS_9ExecStateE
+__ZN3JSC20MarkedArgumentBuffer10slowAppendENS_7JSValueE
+__ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6expan
+__ZN3WTF6VectorIN3JSC8RegisterELm8EE15reserveCapacityEm
+__ZN3WTF9HashTableIPN3JSC20MarkedArgumentBufferES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E4findI
+__ZN3JSCL26stringFromCharCodeSlowCaseEPNS_9ExecStateERKNS_7ArgListE
+__ZN3JSC4Yarr12RegexPattern21newlineCharacterClassEv
+__ZN3JSC10JSFunction12lengthGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC18globalFuncIsFiniteEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC16ArrayConstructor11getCallDataERNS_8CallDataE
 __ZN3JSCL20callArrayConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __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
+__ZN3JSCL19stringProtoFuncTrimEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC15isStrWhiteSpaceEt
+__ZN3JSC6JSCell9getObjectEv
+_ctiOpThrowNotCaught
+__ZN3JSCL22numberProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12NumberObject11getJSNumberEv
+__ZN7WebCore10StringImpl6secureEt
+__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_7JSValueEjPNS_9CodeBlockE
+_cti_op_rshift
+__ZN3JSC13JSNotAnObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3WTF6VectorIN3JSC22AbstractMacroAssemblerINS1_12X86AssemblerEE4JumpELm16EEC2ERKS6_
+__ZN3JSCL21arrayProtoFuncReverseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF21CrossThreadRefCountedINS_16OwnFastMallocPtrIKtEEE5derefEv
+_cti_op_post_inc
+__ZN3JSCL21regExpObjectLastIndexEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
 __ZN3JSC3JIT14emit_op_bitnotEPNS_11InstructionE
 __ZN3JSC3JIT18emitSlow_op_bitnotEPNS_11InstructionERPNS_13SlowCaseEntryE
 __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
+_cti_op_bitnot
+__ZNK3JSC10JSONObject9classInfoEv
+_JSGlobalContextCreate
+_JSGlobalContextCreateInGroup
+__ZN3JSC12JSGlobalData18createContextGroupENS_15ThreadStackTypeE
+__ZN3JSC21createIdentifierTableEv
+__ZN3JSC4Heap29makeUsableFromMultipleThreadsEv
+__ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE
+_JSValueMakeFromJSONString
+_JSValueIsNull
+_JSValueIsUndefined
+_JSValueIsBoolean
+_JSValueIsNumber
+_JSValueIsString
+__ZN3JSC14JSGlobalObject18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+_JSValueIsInstanceOfConstructor
+__ZN3JSC8JSObject11hasInstanceEPNS_9ExecStateENS_7JSValueES3_
+_JSValueToNumber
+_JSObjectGetPropertyAtIndex
+_JSValueToStringCopy
+__ZN14OpaqueJSString6createERKN3JSC7UStringE
+_JSStringCopyCFString
 __ZN3JSC4Heap7destroyEv
 __ZN3JSC4Heap7destroyEv
+__ZN3JSC4Heap10freeBlocksEv
+__ZN3JSC14JSGlobalObjectD1Ev
+__ZN3JSC14JSGlobalObject25destroyJSGlobalObjectDataEPv
 __ZN3JSC12JSGlobalDataD1Ev
 __ZN3JSC12JSGlobalDataD2Ev
 __ZN3JSC12RegisterFileD1Ev
 __ZNK3JSC9HashTable11deleteTableEv
 __ZN3JSC5LexerD1Ev
 __ZN3JSC12JSGlobalDataD1Ev
 __ZN3JSC12JSGlobalDataD2Ev
 __ZN3JSC12RegisterFileD1Ev
 __ZNK3JSC9HashTable11deleteTableEv
 __ZN3JSC5LexerD1Ev
-__ZN3JSC5LexerD2Ev
 __ZN3WTF20deleteAllPairSecondsIP24OpaqueJSClassContextDataKNS_7HashMapIP13OpaqueJSClassS2_NS_7PtrHashIS5_EENS_10HashTraitsIS5_E
 __ZN3JSC17CommonIdentifiersD2Ev
 __ZN3JSC21deleteIdentifierTableEPNS_15IdentifierTableE
 __ZN3WTF20deleteAllPairSecondsIP24OpaqueJSClassContextDataKNS_7HashMapIP13OpaqueJSClassS2_NS_7PtrHashIS5_EENS_10HashTraitsIS5_E
 __ZN3JSC17CommonIdentifiersD2Ev
 __ZN3JSC21deleteIdentifierTableEPNS_15IdentifierTableE
+__ZN3JSC15IdentifierTableD2Ev
 __ZN3JSC4HeapD1Ev
 __ZN3JSC4HeapD1Ev
+__ZN3JSC9JITThunksD1Ev
+__ZN3JSC16NativeExecutableD0Ev
 __ZN3JSC12SmallStringsD1Ev
 __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
-__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
+__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
+__ZN3JSC17ObjectConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL21callObjectConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC9Arguments14deletePropertyEPNS_9ExecStateEj
+__ZN3JSCL18JSONProtoFuncParseEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray11fillArgListEPNS_9ExecStateERNS_20MarkedArgumentBufferE
 __ZN3JSCL17arrayProtoFuncMapEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __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
-__ZN3JSCL18arrayProtoFuncSomeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
-__ZN3JSC12JSNumberCell11getJSNumberEv
-__ZN3JSC23createNotAFunctionErrorEPNS_9ExecStateENS_7JSValueEjPNS_9CodeBlockE
-__ZN3JSC17PrefixBracketNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC17PrefixBracketNodeD0Ev
-__ZN3JSC17RegExpConstructor11getCallDataERNS_8CallDataE
-__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
+__ZN3JSC12StringObjectC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC23MacroAssemblerX86Common9urshift32ENS_12X86Registers10RegisterIDES2_
+_cti_op_urshift
+__ZN3JSC15ObjectPrototype3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSCL21stringProtoFuncConcatEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24regExpConstructorDollar2EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL24regExpConstructorDollar3EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL24regExpConstructorDollar4EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC20MarkedArgumentBuffer9markListsERNS_9MarkStackERN3WTF7HashSetIPS0_NS3_7PtrHashIS5_EENS3_10HashTraitsIS5_EEEE
+__ZN3JSCL22numberProtoFuncToFixedEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16integerPartNoExpEd
+__ZN3JSC10makeStringINS_7UStringES1_PKcS1_EES1_T_T0_T1_T2_
+__ZN3JSC13tryMakeStringINS_7UStringES1_PKcS1_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_T2_
+__ZN3JSCL26numberProtoFuncToPrecisionEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL12charSequenceEci
+__ZN3JSC13tryMakeStringINS_7UStringEPKcS1_S1_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_T2_
+__ZN3JSCL24booleanProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC12JSActivation12toThisObjectEPNS_9ExecStateE
+_cti_op_div
+__ZN3JSC17BytecodeGenerator21emitComplexJumpScopesEPNS_5LabelEPNS_18ControlFlowContextES4_
+__ZN7WebCore10StringImpl7replaceEjjPS0_
+__ZN3JSC12RegExpObject11getCallDataERNS_8CallDataE
+__ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC9ExecState11stringTableEPS0_
+__ZNK3JSC7JSValue16synthesizeObjectEPNS_9ExecStateE
+__ZN3JSC13JSNotAnObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSCL35objectProtoFuncPropertyIsEnumerableEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject20propertyIsEnumerableEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSC7JSArray24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC18PropertyDescriptor13setDescriptorENS_7JSValueEj
+__ZNK3JSC18PropertyDescriptor10enumerableEv
+__ZN3JSCL22JSONProtoFuncStringifyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC11StringifierC2EPNS_9ExecStateENS_7JSValueES3_
+__ZN3JSC11Stringifier9stringifyENS_7JSValueE
+__ZN3JSC11Stringifier22appendStringifiedValueERNS_13StringBuilderENS_7JSValueEPNS_8JSObjectERKNS_27PropertyNameForFunctionCallE
+__ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE
+__ZN3JSC11Stringifier6Holder18appendNextPropertyERS0_RNS_13StringBuilderE
+__ZN3JSC11Stringifier18appendQuotedStringERNS_13StringBuilderERKNS_7UStringE
+__ZN3JSC11StringifierD2Ev
+__ZN3JSC5Lexer19copyCodeWithoutBOMsEv
 __ZN3JSCL21dateProtoFuncSetHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_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
-__ZN3JSC3JIT12emit_op_sretEPNS_11InstructionE
-__ZN3JSC6Parser7reparseINS_8EvalNodeEEEN3WTF10PassRefPtrIT_EEPNS_12JSGlobalDataEPS5_
-__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
-__ZN3JSC18EmptyStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSCL27compareByStringPairForQSortEPKvS1_
+__ZN3JSC17FunctionPrototype11getCallDataERNS_8CallDataE
+__ZN3JSCL28dateProtoFuncGetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10makeStringINS_7UStringES1_EES1_T_T0_
+__ZN3JSC13tryMakeStringINS_7UStringES1_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_
+__ZN3JSC23MacroAssemblerX86Common8branch16ENS0_9ConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE9BaseIndexENS4_5Imm32E
 __Z22jsc_pcre_ucp_othercasej
 __Z22jsc_pcre_ucp_othercasej
-__ZN3JSCL35objectProtoFuncPropertyIsEnumerableEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__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
-__ZN3JSC18BooleanConstructor11getCallDataERNS_8CallDataE
-__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
-__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_14Pa
-__ZN24OpaqueJSClassContextDataC2EP13OpaqueJSClass
-__ZN3JSC7UString3Rep13createCopyingEPKti
-_JSObjectSetProperty
-__ZNK14OpaqueJSString10identifierEPN3JSC12JSGlobalDataE
-__ZN3JSC14JSGlobalObject17putWithAttributesEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueEj
-_JSStringRelease
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEE18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEE20staticFunctionGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSC18JSCallbackFunctionC1EPNS_9ExecStateEPFPK13OpaqueJSValuePK15OpaqueJSContextPS3_S9_mPKS5_PS5_ERKNS_10IdentifierE
-__ZN3JSC18JSCallbackFunction11getCallDataERNS_8CallDataE
-__ZN3JSC18JSCallbackFunction4callEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE
-_JSObjectGetPrivate
-__ZNK3JSC16JSCallbackObjectINS_8JSObjectEE9classInfoEv
-_JSValueMakeUndefined
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEE17staticValueGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN14OpaqueJSString6createERKN3JSC7UStringE
-_JSStringCreateWithCharacters
-_JSValueMakeString
-__ZNK14OpaqueJSString7ustringEv
-__ZN3JSC7UStringC1EPtib
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEED1Ev
-_JSClassRelease
-__ZL25clearReferenceToPrototypeP13OpaqueJSValue
-_JSObjectGetProperty
-_JSValueToObject
-__ZN3JSCL22dateProtoFuncGetUTCDayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL24dateProtoFuncGetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC8JSString18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSCL24dateProtoFuncSetUTCHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncSetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL26dateProtoFuncSetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL23dateProtoFuncGetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL23dateProtoFuncGetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL27dateProtoFuncGetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZNK3JSC7UString8toUInt32EPb
+__ZN3JSCL23dateProtoFuncSetUTCDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL24dateProtoFuncGetUTCHoursEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL26dateProtoFuncGetUTCMinutesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL26dateProtoFuncGetUTCSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __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
+__ZN3JSCL24dateProtoFuncSetFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF6VectorIiLm32EE15reserveCapacityEm
+__ZN3JSCL22regExpProtoFuncCompileEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC27PropertyNameForFunctionCall5valueEPNS_9ExecStateE
+_cti_op_new_error
+__ZN7WebCore6String6numberEj
+__ZN3JSCL27dateProtoFuncGetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncGetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL31dateProtoFuncToLocaleDateStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16formatLocaleDateEPNS_9ExecStateEPNS_12DateInstanceEdNS_20LocaleDateTimeFormatERKNS_7ArgListE
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
+__ZN3JSCL23throwStackOverflowErrorEPNS_9ExecStateEPNS_12JSGlobalDataENS_16ReturnAddressPtrERS4_
+__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
+__ZN3JSC12RegisterFile21releaseExcessCapacityEv
+__ZN3JSC12StringObject18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
+__ZN3JSC19FunctionConstructor11getCallDataERNS_8CallDataE
+__ZN7WebCore6String8fromUTF8EPKc
+__ZN3JSCL27dateProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC18BooleanConstructor16getConstructDataERNS_13ConstructDataE
 __ZN3JSCL31constructWithBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
 __ZN3JSC16constructBooleanEPNS_9ExecStateERKNS_7ArgListE
 __ZN3JSC18BooleanConstructor16getConstructDataERNS_13ConstructDataE
 __ZN3JSCL31constructWithBooleanConstructorEPNS_9ExecStateEPNS_8JSObjectERKNS_7ArgListE
 __ZN3JSC16constructBooleanEPNS_9ExecStateERKNS_7ArgListE
-__ZN3JSCL31dateProtoFuncGetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL28dateProtoFuncGetMilliSecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC7JSArray11sortNumericEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataE
+__ZN3JSCL22compareNumbersForQSortEPKvS1_
+__ZN3WTF6VectorIjLm16EE15reserveCapacityEm
+__ZN3JSC8JSString16getIndexSlowCaseEPNS_9ExecStateEj
+__ZN3JSCL25numberConstructorNaNValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
+__ZN3JSC4Yarr15nondigitsCreateEv
+__ZN3JSCL7dateUTCEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC7ArgList2atEm
+__ZN3JSCL16mathProtoFuncTanEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC8JSObject16isVariableObjectEv
+__ZN7WebCore6String6insertERKS0_j
+__ZN7WebCore6String6insertEPKtjj
+__ZN7WebCore10StringImpl37createStrippingNullCharactersSlowCaseEPKtj
 __ZN3JSCL31dateProtoFuncToLocaleTimeStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL31dateProtoFuncToLocaleTimeStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL21regExpObjectLastIndexEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3WTF7CString11mutableDataEv
+__ZN3WTF7CString18copyBufferIfNeededEv
+__ZN3JSCL18arrayProtoFuncSomeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC21DebuggerStatementNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __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
+__ZN3JSCL31dateProtoFuncGetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF15ThreadConditionD1Ev
+__ZN3JSC18RegExpMatchesArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3WTF6VectorIPNS0_IN3JSC10IdentifierELm64EEELm32EE14expandCapacityEm
+__ZN3JSC15DateConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL8callDateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL22dateProtoFuncGetUTCDayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL25arrayProtoFuncLastIndexOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL19arrayProtoFuncEveryEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23callFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL19stringProtoFuncLinkEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL25dateProtoFuncToDateStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE
+__ZN3JSCL27dateProtoFuncSetUTCFullYearEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24dateProtoFuncSetUTCMonthEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL31dateProtoFuncSetUTCMillisecondsEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN7WebCore6String6numberEx
 __ZNK3JSC17NumberConstructor9classInfoEv
 __ZNK3JSC17RegExpConstructor9classInfoEv
 __ZNK3JSC17NumberConstructor9classInfoEv
 __ZNK3JSC17RegExpConstructor9classInfoEv
-__ZN3JSCL31dateProtoFuncToLocaleDateStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3WTF9HashTableINS_6RefPtrIN7WebCore10StringImplEEESt4pairIS4_P19StaticFunctionEntryENS_18PairFirstExtractorIS8_EENS2_10Stri
+__ZN3WTF9HashTableINS_6RefPtrIN7WebCore10StringImplEEESt4pairIS4_P16StaticValueEntryENS_18PairFirstExtractorIS8_EENS2_10StringH
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE20staticFunctionGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC18JSCallbackFunctionC1EPNS_9ExecStateEPFPK13OpaqueJSValuePK15OpaqueJSContextPS3_S9_mPKS5_PS5_ERKNS_10IdentifierE
+__ZN3JSC18JSCallbackFunction11getCallDataERNS_8CallDataE
+__ZN3JSC18JSCallbackFunction4callEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC6JSLock12DropAllLocksC1EPNS_9ExecStateE
+_JSValueMakeUndefined
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE17staticValueGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+_JSValueMakeString
+__ZN3JSC18JSCallbackFunctionD1Ev
+_JSValueMakeBoolean
+_JSStringCreateWithCharacters
+_JSValueMakeNumber
+__ZN3JSC4Heap6isBusyEv
+__ZN7WebCore10StringImpl7replaceEtPS0_
 __ZNK3JSC8JSObject14isGlobalObjectEv
 __ZNK3JSC8JSObject14isGlobalObjectEv
-_JSValueToBoolean
-__ZN3JSC8JITStubs13cti_op_lshiftEPPv
-__ZN3JSC8JITStubs13cti_op_bitnotEPPv
-__ZN3JSC6JSCell3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC19FunctionConstructor11getCallDataERNS_8CallDataE
+__ZNK7WebCore6String5splitEtbRN3WTF6VectorIS0_Lm0EEE
+__ZN7WebCore6String6appendEt
+__ZNK3JSC7UString8toUInt32EPb
 __ZN3WTF9ByteArray6createEm
 __ZN3WTF9ByteArray6createEm
-__ZNK3JSC6JSCell9getStringERNS_7UStringE
-__ZN3JSC3JIT12emit_op_loopEPNS_11InstructionE
-__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
-__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
-__ZN3JSC11JSByteArrayC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
+__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
+__ZN3JSC11JSByteArrayC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
 __ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
 __ZN3JSC11JSByteArray3putEPNS_9ExecStateEjNS_7JSValueE
 __ZN3JSC11JSByteArray3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __ZN3JSC11JSByteArray18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
 __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
+_cti_op_get_by_val_byte_array
+_cti_op_put_by_val_byte_array
+_JSStringGetUTF8CString
+__ZN3JSC16JSVariableObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
 __ZNK3JSC22NativeErrorConstructor9classInfoEv
 __ZNK3JSC16JSCallbackObjectINS_8JSObjectEE9classNameEv
 __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
+__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
+__ZN3JSC26createNotAConstructorErrorEPNS_9ExecStateENS_7JSValueEjPNS_9CodeBlockE
+__ZNK3JSC4Heap11objectCountEv
+__ZN3JSC14JSGlobalObject12defineGetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
+__ZN3JSC14JSGlobalObject12defineSetterEPNS_9ExecStateERKNS_10IdentifierEPNS_8JSObjectEj
 __ZN3JSC9Structure22getterSetterTransitionEPS0_
 __ZN3JSC9Structure22getterSetterTransitionEPS0_
-__ZN3JSC8JSObject22fillGetterPropertySlotERNS_12PropertySlotEPNS_7JSValueE
-__ZN3JSC12PropertySlot14functionGetterEPNS_9ExecStateERKNS_10IdentifierERKS0_
 __ZN3JSCL28objectProtoFuncIsPrototypeOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL28objectProtoFuncIsPrototypeOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC12StringObjectC2EPNS_9ExecStateEN3WTF10PassRefPtrINS_9StructureEEERKNS_7UStringE
-__ZNK3JSC7UString6is8BitEv
-__ZN3JSC8JSObject15unwrappedObjectEv
-__ZN3JSC22NativeErrorConstructor11getCallDataERNS_8CallDataE
 __ZN3JSC16JSCallbackObjectINS_8JSObjectEE11getCallDataERNS_8CallDataE
 __ZN3JSC16JSCallbackObjectINS_8JSObjectEE11getCallDataERNS_8CallDataE
-__ZN3JSC17BytecodeGenerator21emitComplexJumpScopesEPNS_5LabelEPNS_18ControlFlowContextES4_
-__ZN3JSC23ThrowableExpressionData14emitThrowErrorERNS_17BytecodeGeneratorENS_9ErrorTypeEPKc
-__ZN3JSC17BytecodeGenerator12emitNewErrorEPNS_10RegisterIDENS_9ErrorTypeENS_7JSValueE
-__ZN3JSC3JIT17emit_op_new_errorEPNS_11InstructionE
-__ZN3JSC23MacroAssemblerX86Common8branch16ENS0_9ConditionENS_22AbstractMacroAssemblerINS_12X86AssemblerEE9BaseIndexENS4_5Imm32E
-_JSStringRetain
-__ZN3JSCL19arrayProtoFuncEveryEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL23arrayConstructorIsArrayEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21objectConstructorKeysEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12DateInstanceC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEd
+__ZN3JSC12DateInstanceC2EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEd
+__ZN3JSCL24dateProtoFuncToISOStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC15createTypeErrorEPNS_9ExecStateEPKc
+__ZNK3JSC11JSByteArray9classInfoEv
+__ZN3JSC11JSByteArray19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC22NativeErrorConstructor11getCallDataERNS_8CallDataE
+__ZN3JSCL36objectConstructorGetOwnPropertyNamesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL41objectConstructorGetOwnPropertyDescriptorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC8JSObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZNK3JSC18PropertyDescriptor20isAccessorDescriptorEv
+__ZNK3JSC18PropertyDescriptor8writableEv
+__ZNK3JSC18PropertyDescriptor12configurableEv
+__ZN3JSC12JSGlobalData6createENS_15ThreadStackTypeE
+__ZN3JSC12JSGlobalData10ClientDataD2Ev
+__ZN3WTF14ThreadSpecificINS_13WTFThreadDataEE7destroyEPv
+__ZN3WTF13WTFThreadDataD1Ev
+__ZN7WebCore17AtomicStringTable7destroyEPS0_
+__ZN3JSC15IdentifierTableD1Ev
+__ZN3WTF9dayInYearEdi
+__ZN3WTF18monthFromDayInYearEib
+__ZN3WTF23dayInMonthFromDayInYearEib
+__ZN3JSC6Walker4walkENS_7JSValueE
+__ZN3WTF9HashTableIPN7WebCore10StringImplES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_EC2ERKSA_
+__ZN3WTF6VectorIPN3JSC7JSArrayELm16EE14expandCapacityEm
+__ZN3WTF6VectorIjLm16EE14expandCapacityEm
+__ZN3WTF6VectorIN3JSC11WalkerStateELm16EE14expandCapacityEm
+__ZL30makeGetterOrSetterPropertyNodePN3JSC12JSGlobalDataERKNS_10IdentifierES4_PNS_13ParameterNodeEPNS_16FunctionBodyNodeERKNS_1
+__ZN3JSC17BytecodeGenerator13emitPutGetterEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC3JIT18emit_op_put_getterEPNS_11InstructionE
+_cti_op_put_getter
+__ZN3JSCL23booleanProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL19dateProtoFuncToJSONEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC9ExecState9dateTableEPS0_
+__ZN3JSC10Identifier4fromEPNS_9ExecStateEd
+__ZN3JSC13StringBuilder6appendEt
+__ZN3JSC17BytecodeGenerator13emitPutSetterEPNS_10RegisterIDERKNS_10IdentifierES2_
+__ZN3JSC3JIT18emit_op_put_setterEPNS_11InstructionE
+_cti_op_put_setter
+__ZN3JSCL23objectConstructorCreateEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL16definePropertiesEPNS_9ExecStateEPNS_8JSObjectES3_
+__ZN3JSCL20toPropertyDescriptorEPNS_9ExecStateENS_7JSValueERNS_18PropertyDescriptorE
+__ZN3JSC18PropertyDescriptor13setEnumerableEb
+__ZN3WTF6VectorIN3JSC18PropertyDescriptorELm0EE14expandCapacityEm
+__ZNK3JSC18PropertyDescriptor16isDataDescriptorEv
+__ZN3JSC8JSObject17defineOwnPropertyEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorEb
+__ZN3JSCL13putDescriptorEPNS_9ExecStateEPNS_8JSObjectERKNS_10IdentifierERNS_18PropertyDescriptorEjNS_7JSValueE
+__ZNK3JSC18PropertyDescriptor19isGenericDescriptorEv
+__ZN3JSCL31objectConstructorGetPrototypeOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC18PropertyDescriptor9setGetterENS_7JSValueE
+__ZNK3JSC18PropertyDescriptor6getterEv
+__ZNK3JSC18PropertyDescriptor6setterEv
+__ZN3JSC18PropertyDescriptor15setConfigurableEb
+__ZN3JSC18PropertyDescriptor11setWritableEb
+__ZN3JSC18PropertyDescriptor9setSetterENS_7JSValueE
+__ZN3JSCL33objectConstructorDefinePropertiesEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZNK3JSC18PropertyDescriptor7equalToEPNS_9ExecStateERKS0_
+__ZNK3JSC18PropertyDescriptor15attributesEqualERKS0_
+__ZNK3JSC18PropertyDescriptor22attributesWithOverrideERKS0_
+__ZN3JSCL31objectConstructorDefinePropertyEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC9ExecState11regExpTableEPS0_
+__ZN3JSC9Arguments19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayENS_15EnumerationModeE
+__ZN3JSC9ExecState11numberTableEPS0_
+__ZN3JSC9ExecState22regExpConstructorTableEPS0_
+__ZNK3JSC15RegExpPrototype9classInfoEv
+__ZNK3JSC10MathObject9classInfoEv
+__ZN3JSC9ExecState9mathTableEPS0_
+__ZN3JSC9ExecState9jsonTableEPS0_
 __ZN3JSCL20arrayProtoFuncReduceEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL25arrayProtoFuncReduceRightEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL28arrayProtoFuncToLocaleStringEPNS_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
 __ZN3JSC19JSStaticScopeObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
-__ZN3JSC9ExecState9dateTableEPS0_
-__ZNK3JSC15RegExpPrototype9classInfoEv
-__ZN3JSC12StringObject14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSCL25dateProtoFuncToDateStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL25dateProtoFuncToTimeStringEPNS_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
+__ZN3JSC7JSValueC1EPNS_9ExecStateEd
 __ZN3JSC15DeleteValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC15DeleteValueNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC15DeleteValueNodeD0Ev
 __ZN3JSC16PostfixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC16PostfixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
+__ZN3JSC23ThrowableExpressionData14emitThrowErrorERNS_17BytecodeGeneratorENS_9ErrorTypeEPKcRKNS_7UStringE
+__ZN3JSC10makeStringINS_7UStringES1_S1_EES1_T_T0_T1_
+__ZN3JSC13tryMakeStringINS_7UStringES1_S1_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_
 __ZN3JSC15PrefixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
 __ZN3JSC15PrefixErrorNode12emitBytecodeERNS_17BytecodeGeneratorEPNS_10RegisterIDE
-__ZN3JSC16PostfixErrorNodeD0Ev
-__ZN3JSC15PrefixErrorNodeD0Ev
 __ZN3JSC23createInvalidParamErrorEPNS_9ExecStateEPKcNS_7JSValueEjPNS_9CodeBlockE
 __ZN3JSC23createInvalidParamErrorEPNS_9ExecStateEPKcNS_7JSValueEjPNS_9CodeBlockE
+__ZN3JSC10makeStringIPKcS2_S2_EENS_7UStringET_T0_T1_
+__ZN3JSC13tryMakeStringIPKcS2_S2_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_T1_
 __ZNK3JSC15DotAccessorNode17isDotAccessorNodeEv
 __ZNK3JSC14ExpressionNode17isDotAccessorNodeEv
 __ZN3JSC13JSNotAnObject3putEPNS_9ExecStateEjNS_7JSValueE
 __ZNK3JSC15DotAccessorNode17isDotAccessorNodeEv
 __ZNK3JSC14ExpressionNode17isDotAccessorNodeEv
 __ZN3JSC13JSNotAnObject3putEPNS_9ExecStateEjNS_7JSValueE
-__ZN3JSC4Heap24setGCProtectNeedsLockingEv
-__ZN3JSCL23callFunctionConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC14ArrayPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC13DatePrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC15StringPrototype24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC8JSString27getStringPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC17NumberConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC17RegExpConstructor24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSCL22regExpConstructorInputEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSC12RegExpObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC10MathObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC18RegExpMatchesArray24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC10JSFunction24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
+__ZN3JSC11JSByteArray24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
 __ZNK3JSC16JSCallbackObjectINS_8JSObjectEE8toStringEPNS_9ExecStateE
 __ZNK3JSC16JSCallbackObjectINS_8JSObjectEE8toStringEPNS_9ExecStateE
-__ZN3JSC8JITStubs17cti_op_instanceofEPPv
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringEilS5_
 __ZN3JSC17BytecodeGenerator35emitThrowExpressionTooDeepExceptionEv
 __ZN3JSC17BytecodeGenerator35emitThrowExpressionTooDeepExceptionEv
-__ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL17mathProtoFuncACosEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL25numberConstructorMinValueEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
 __ZN3JSCL18mathProtoFuncATan2EPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL18mathProtoFuncATan2EPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL16mathProtoFuncTanEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL28numberProtoFuncToExponentialEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL28numberProtoFuncToExponentialEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL26numberProtoFuncToPrecisionEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSCL12charSequenceEci
+__ZN3JSC16parseIntOverflowEPKcii
 __ZN3JSCL29objectProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSCL29objectProtoFuncToLocaleStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
-__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
-__ZN3JSCL27objectProtoFuncLookupSetterEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
-__ZN3JSC8JSObject12lookupSetterEPNS_9ExecStateERKNS_10IdentifierE
-__ZN3JSC9ExecState22regExpConstructorTableEPS0_
-__ZN3JSCL24regExpConstructorDollar7EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar8EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL24regExpConstructorDollar9EPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL22regExpConstructorInputEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL24regExpConstructorDollar5EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL24regExpConstructorDollar6EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL24regExpConstructorDollar7EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL24regExpConstructorDollar8EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL24regExpConstructorDollar9EPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
 __ZN3JSCL25setRegExpConstructorInputEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
 __ZN3JSCL25setRegExpConstructorInputEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
-__ZN3JSCL26regExpConstructorLastMatchEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL26regExpConstructorLastParenEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL26regExpConstructorMultilineEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
+__ZN3JSCL26regExpConstructorLastMatchEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZN3JSCL26regExpConstructorLastParenEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+__ZNK3JSC17RegExpConstructor12getLastParenEPNS_9ExecStateE
+__ZN3JSCL26regExpConstructorMultilineEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
 __ZN3JSCL29setRegExpConstructorMultilineEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
 __ZN3JSCL29setRegExpConstructorMultilineEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueE
-__ZN3JSC4Yarr15nondigitsCreateEv
+__ZNK3JSC17RegExpConstructor5inputEv
+__ZN3JSC10makeStringIPKcS2_EENS_7UStringET_T0_
+__ZN3JSC13tryMakeStringIPKcS2_EEN3WTF10PassRefPtrIN7WebCore10StringImplEEET_T0_
+__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringE
 __ZNK3JSC19JSStaticScopeObject12toThisObjectEPNS_9ExecStateE
 __ZNK3JSC19JSStaticScopeObject12toThisObjectEPNS_9ExecStateE
+__ZN3JSCL23stringProtoFuncTrimLeftEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL24stringProtoFuncTrimRightEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3JSC12JSActivation18getArgumentsGetterEv
 __ZN3JSC12JSActivation18getArgumentsGetterEv
-__ZN3JSC12JSActivation15argumentsGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-__ZN3JSCL23booleanProtoFuncValueOfEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC12JSActivation15argumentsGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
 __ZN3JSCL28stringProtoFuncLocaleCompareEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3WTF8Collator11userDefaultEv
 __ZNK3WTF8Collator7collateEPKtmS2_m
 __ZNK3WTF8Collator14createCollatorEv
 __ZN3WTF8CollatorD1Ev
 __ZN3WTF8Collator15releaseCollatorEv
 __ZN3JSCL28stringProtoFuncLocaleCompareEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3WTF8Collator11userDefaultEv
 __ZNK3WTF8Collator7collateEPKtmS2_m
 __ZNK3WTF8Collator14createCollatorEv
 __ZN3WTF8CollatorD1Ev
 __ZN3WTF8Collator15releaseCollatorEv
-__ZNK3JSC10MathObject9classInfoEv
-__ZN3JSC9ExecState9mathTableEPS0_
+__ZN3JSC9Arguments14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
+__ZN3JSCL26callNativeErrorConstructorEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSCL21callFunctionPrototypeEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
+__ZN3JSC6JSCell11getJSNumberEv
+__ZN3JSCL16callRegExpObjectEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_7ArgListE
 __ZN3WTF6VectorIN3JSC20FunctionRegisterInfoELm0EE14expandCapacityEm
 __ZN3JSC3JIT25emit_op_profile_will_callEPNS_11InstructionE
 __ZN3JSC3JIT24emit_op_profile_did_callEPNS_11InstructionE
 __ZN3WTF6VectorIN3JSC20FunctionRegisterInfoELm0EE14expandCapacityEm
 __ZN3JSC3JIT25emit_op_profile_will_callEPNS_11InstructionE
 __ZN3JSC3JIT24emit_op_profile_did_callEPNS_11InstructionE
@@ -1873,18 +2052,18 @@ __ZN3JSC16ProfileGeneratorC2ERKNS_7UStringEPNS_9ExecStateEj
 __ZN3JSC7Profile6createERKNS_7UStringEj
 __ZN3JSC7ProfileC2ERKNS_7UStringEj
 __ZN3JSC11ProfileNodeC1ERKNS_14CallIdentifierEPS0_S4_
 __ZN3JSC7Profile6createERKNS_7UStringEj
 __ZN3JSC7ProfileC2ERKNS_7UStringEj
 __ZN3JSC11ProfileNodeC1ERKNS_14CallIdentifierEPS0_S4_
-__ZN3JSC33getCurrentUTCTimeWithMicrosecondsEv
 __ZN3JSC16ProfileGenerator24addParentForConsoleStartEPNS_9ExecStateE
 __ZN3JSC16ProfileGenerator24addParentForConsoleStartEPNS_9ExecStateE
-__ZN3JSC8Profiler20createCallIdentifierEPNS_12JSGlobalDataENS_7JSValueERKNS_7UStringEi
-__ZN3JSC16InternalFunction21calculatedDisplayNameEPNS_12JSGlobalDataE
+__ZN3JSC8Profiler20createCallIdentifierEPNS_9ExecStateENS_7JSValueERKNS_7UStringEi
+__ZN3JSC16InternalFunction21calculatedDisplayNameEPNS_9ExecStateE
+__ZN3JSC16InternalFunction11displayNameEPNS_9ExecStateE
 __ZN3JSC11ProfileNode10insertNodeEN3WTF10PassRefPtrIS0_EE
 __ZN3WTF6VectorINS_6RefPtrIN3JSC11ProfileNodeEEELm0EE14expandCapacityEm
 __ZN3JSC11ProfileNode10insertNodeEN3WTF10PassRefPtrIS0_EE
 __ZN3WTF6VectorINS_6RefPtrIN3JSC11ProfileNodeEEELm0EE14expandCapacityEm
-__ZN3WTF6VectorINS_6RefPtrIN3JSC16ProfileGeneratorEEELm0EE14expandCapacityEm
-__ZN3JSC8JITStubs23cti_op_profile_did_callEPPv
+__ZN3WTF6VectorINS_6RefPtrIN3JSC16ProfileGeneratorEEELm0EE15reserveCapacityEm
+_cti_op_profile_did_call
 __ZN3JSC8Profiler10didExecuteEPNS_9ExecStateENS_7JSValueE
 __ZN3JSC16ProfileGenerator10didExecuteERKNS_14CallIdentifierE
 __ZN3JSC11ProfileNode10didExecuteEv
 __ZN3JSC8Profiler10didExecuteEPNS_9ExecStateENS_7JSValueE
 __ZN3JSC16ProfileGenerator10didExecuteERKNS_14CallIdentifierE
 __ZN3JSC11ProfileNode10didExecuteEv
-__ZN3JSC8JITStubs24cti_op_profile_will_callEPPv
+_cti_op_profile_will_call
 __ZN3JSC8Profiler11willExecuteEPNS_9ExecStateENS_7JSValueE
 __ZN3JSC16ProfileGenerator11willExecuteERKNS_14CallIdentifierE
 __ZN3JSC11ProfileNode11willExecuteERKNS_14CallIdentifierE
 __ZN3JSC8Profiler11willExecuteEPNS_9ExecStateENS_7JSValueE
 __ZN3JSC16ProfileGenerator11willExecuteERKNS_14CallIdentifierE
 __ZN3JSC11ProfileNode11willExecuteERKNS_14CallIdentifierE
@@ -1893,71 +2072,64 @@ __ZN3JSC16ProfileGenerator13stopProfilingEv
 __ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE
 __ZNK3JSC11ProfileNode25traverseNextNodePostOrderEv
 __ZN3JSC11ProfileNode13stopProfilingEv
 __ZN3JSC7Profile7forEachEMNS_11ProfileNodeEFvvE
 __ZNK3JSC11ProfileNode25traverseNextNodePostOrderEv
 __ZN3JSC11ProfileNode13stopProfilingEv
-__ZN3JSCeqERKNS_7UStringEPKc
 __ZN3JSC11ProfileNode11removeChildEPS0_
 __ZN3JSC11ProfileNode8addChildEN3WTF10PassRefPtrIS0_EE
 __ZN3JSC11ProfileNode11removeChildEPS0_
 __ZN3JSC11ProfileNode8addChildEN3WTF10PassRefPtrIS0_EE
-_JSValueIsObjectOfClass
-_JSObjectCallAsConstructor
-__ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13ConstructDataERKNS_7ArgListE
-_JSObjectCallAsFunction
-__ZN3JSC4Heap14primaryHeapEndEv
+__ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE
 __ZN3JSC4Heap16primaryHeapBeginEv
 __ZN3JSC4Heap16primaryHeapBeginEv
+__ZN3JSC4Heap14primaryHeapEndEv
 __ZNK3JSC18JSCallbackFunction9classInfoEv
 __ZNK3JSC18JSCallbackFunction9classInfoEv
+__ZN3WTF7HashSetIPN3JSC18FunctionExecutableENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
+__ZN3WTF9HashTableIPN3JSC18FunctionExecutableES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6expandE
+__ZN3JSC18FunctionExecutable9recompileEPNS_9ExecStateE
 __ZN3JSC8Profiler11willExecuteEPNS_9ExecStateERKNS_7UStringEi
 __ZN3JSC8Profiler10didExecuteEPNS_9ExecStateERKNS_7UStringEi
 __ZNK3JSC16ProfileGenerator5titleEv
 __ZN3JSC8Profiler11willExecuteEPNS_9ExecStateERKNS_7UStringEi
 __ZN3JSC8Profiler10didExecuteEPNS_9ExecStateERKNS_7UStringEi
 __ZNK3JSC16ProfileGenerator5titleEv
+__ZN3JSC9CodeBlock33functionRegisterForBytecodeOffsetEjRi
 __ZN3JSC7ProfileD0Ev
 __ZN3WTF10RefCountedIN3JSC11ProfileNodeEE5derefEv
 __ZN3JSC7ProfileD0Ev
 __ZN3WTF10RefCountedIN3JSC11ProfileNodeEE5derefEv
-__ZN3JSC4Yarr14RegexGenerator33generatePatternCharacterNonGreedyERNS1_19TermGenerationStateE
-__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
-__ZNK3JSC25InterruptedExecutionError19isWatchdogExceptionEv
-__ZN3JSC25InterruptedExecutionErrorD1Ev
-__ZN3JSC12JSGlobalData10ClientDataD2Ev
-__ZN3JSC18RegExpMatchesArray16getPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArrayE
+__ZN3JSC34createTerminatedExecutionExceptionEPNS_12JSGlobalDataE
+__ZNK3JSC24TerminatedExecutionError13exceptionTypeEv
+__ZN3JSC24TerminatedExecutionErrorD1Ev
 __ZN3WTF8CollatorC1EPKc
 __ZN3WTF8Collator18setOrderLowerFirstEb
 __ZN3WTF8CollatorC1EPKc
 __ZN3WTF8Collator18setOrderLowerFirstEb
+_JSValueIsEqual
+__ZN3JSC7JSValue13equalSlowCaseEPNS_9ExecStateES0_S0_
+__ZNK3JSC14JSGlobalObject17supportsProfilingEv
+__ZNK7WebCore6String12toUIntStrictEPbi
+__ZN7WebCore10StringImpl12toUIntStrictEPbi
 __ZN3WTF12randomNumberEv
 __ZN3WTF12randomNumberEv
+__ZNK7WebCore6String8toUInt64EPb
+__ZN7WebCore10StringImpl8toUInt64EPb
+__ZN7WebCore18charactersToUInt64EPKtmPb
+_JSStringGetMaximumUTF8CStringSize
 __ZN3JSC16JSCallbackObjectINS_8JSObjectEE3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
 __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
+__ZN7WebCore6String6numberEm
 __ZN3JSC4Heap17globalObjectCountEv
 __ZN3JSC4Heap20protectedObjectCountEv
 __ZN3JSC4Heap25protectedObjectTypeCountsEv
 __ZN3WTF9HashTableIPKcSt4pairIS2_jENS_18PairFirstExtractorIS4_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSA_I
 __ZN3JSC4Heap17globalObjectCountEv
 __ZN3JSC4Heap20protectedObjectCountEv
 __ZN3JSC4Heap25protectedObjectTypeCountsEv
 __ZN3WTF9HashTableIPKcSt4pairIS2_jENS_18PairFirstExtractorIS4_EENS_7PtrHashIS2_EENS_14PairHashTraitsINS_10HashTraitsIS2_EENSA_I
+__ZNK3JSC6JSCell17isAPIValueWrapperEv
+__ZNK3JSC6JSCell22isPropertyNameIteratorEv
+__ZN3JSC4Heap16objectTypeCountsEv
+__ZNK3JSC22JSPropertyNameIterator22isPropertyNameIteratorEv
 __ZN3WTF20fastMallocStatisticsEv
 __ZNK3JSC4Heap10statisticsEv
 __ZN3WTF27releaseFastMallocFreeMemoryEv
 __ZN3WTF20fastMallocStatisticsEv
 __ZNK3JSC4Heap10statisticsEv
 __ZN3WTF27releaseFastMallocFreeMemoryEv
-__ZN3JSC10JSFunction16getConstructDataERNS_13ConstructDataE
-__ZN3JSC10JSFunction9constructEPNS_9ExecStateERKNS_7ArgListE
+_JSStringIsEqualToUTF8CString
+__ZN3JSC16JSCallbackObjectINS_8JSObjectEE14callbackGetterEPNS_9ExecStateENS_7JSValueERKNS_10IdentifierE
+_JSObjectSetPrivate
 __ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
 __ZN3JSC8Debugger6attachEPNS_14JSGlobalObjectE
-__ZN3WTF7HashSetIPN3JSC14JSGlobalObjectENS_7PtrHashIS3_EENS_10HashTraitsIS3_EEE3addERKS3_
 __ZN3WTF9HashTableIPN3JSC14JSGlobalObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
 __ZN3WTF9HashTableIPN3JSC14JSGlobalObjectES3_NS_17IdentityExtractorIS3_EENS_7PtrHashIS3_EENS_10HashTraitsIS3_EES9_E6rehashEi
+__ZN3WTF9HashTableIPN3JSC14SourceProviderESt4pairIS3_PNS1_9ExecStateEENS_18PairFirstExtractorIS7_EENS_7PtrHashIS3_EENS_14PairHa
+__ZN3JSC7UString4fromEl
 __ZN3JSC3JIT13emit_op_debugEPNS_11InstructionE
 __ZN3JSC3JIT13emit_op_debugEPNS_11InstructionE
-__ZN3JSC8JITStubs12cti_op_debugEPPv
+_cti_op_debug
 __ZN3JSC11Interpreter5debugEPNS_9ExecStateENS_11DebugHookIDEii
 __ZN3JSC11Interpreter5debugEPNS_9ExecStateENS_11DebugHookIDEii
+__ZNK3JSC17DebuggerCallFrame4typeEv
+__ZNK3JSC17DebuggerCallFrame22calculatedFunctionNameEv
+__ZNK3JSC12JSActivation18isActivationObjectEv
+__ZNK3JSC17DebuggerCallFrame10thisObjectEv
+__ZN3WTF28setMainThreadCallbacksPausedEb
+__ZNK3JSC17DebuggerCallFrame8evaluateERKNS_7UStringERNS_7JSValueE
 __ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
 __ZN3JSC8Debugger6detachEPNS_14JSGlobalObjectE
-__ZN3JSC9CodeBlock33functionRegisterForBytecodeOffsetEjRi
-_JSStringIsEqualToUTF8CString
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEE14callbackGetterEPNS_9ExecStateERKNS_10IdentifierERKNS_12PropertySlotE
-_JSObjectSetPrivate
-__ZN3JSC7UString3Rep11computeHashEPKci
-__ZN3JSC16JSCallbackObjectINS_8JSObjectEE14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
-_JSGarbageCollect
-__ZN3JSC4Heap6isBusyEv
-__ZN3JSCL18styleFromArgStringERKNS_7UStringEl
+_JSValueIsObjectOfClass
index 75737aed66fe43ac0e1d63947b85e129523cbeb2..de5505f021af7a7220f0665345c52a897bd7ca3f 100644 (file)
@@ -1,21 +1,28 @@
 # JavaScriptCore - Qt4 build info
 VPATH += $$PWD
 # JavaScriptCore - Qt4 build info
 VPATH += $$PWD
-
+CONFIG(debug, debug|release) {
+    # Output in JavaScriptCore/<config>
+    JAVASCRIPTCORE_DESTDIR = debug
+    # Use a config-specific target to prevent parallel builds file clashes on Mac
+    JAVASCRIPTCORE_TARGET = jscored
+} else {
+    JAVASCRIPTCORE_DESTDIR = release
+    JAVASCRIPTCORE_TARGET = jscore
+}
 CONFIG(standalone_package) {
     isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = $$PWD/generated
 } else {
     isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = generated
 }
 
 CONFIG(standalone_package) {
     isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = $$PWD/generated
 } else {
     isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = generated
 }
 
-CONFIG(debug, debug|release) {
-    OBJECTS_DIR = obj/debug
-} else { # Release
-    OBJECTS_DIR = obj/release
-}
+CONFIG(standalone_package): DEFINES *= NDEBUG
 
 symbian: {
     # Need to guarantee this comes before system includes of /epoc32/include
     MMP_RULES += "USERINCLUDE ../JavaScriptCore/profiler"
 
 symbian: {
     # Need to guarantee this comes before system includes of /epoc32/include
     MMP_RULES += "USERINCLUDE ../JavaScriptCore/profiler"
+    LIBS += -lhal
+    # For hal.h
+    INCLUDEPATH *= $$MW_LAYER_SYSTEMINCLUDE
 }
 
 INCLUDEPATH = \
 }
 
 INCLUDEPATH = \
@@ -31,8 +38,8 @@ INCLUDEPATH = \
     $$PWD/pcre \
     $$PWD/profiler \
     $$PWD/runtime \
     $$PWD/pcre \
     $$PWD/profiler \
     $$PWD/runtime \
-    $$PWD/wrec \
     $$PWD/wtf \
     $$PWD/wtf \
+    $$PWD/wtf/symbian \
     $$PWD/wtf/unicode \
     $$PWD/yarr \
     $$PWD/API \
     $$PWD/wtf/unicode \
     $$PWD/yarr \
     $$PWD/API \
@@ -40,11 +47,10 @@ INCLUDEPATH = \
     $$JSC_GENERATED_SOURCES_DIR \
     $$INCLUDEPATH
 
     $$JSC_GENERATED_SOURCES_DIR \
     $$INCLUDEPATH
 
+win32-*: DEFINES += _HAS_TR1=0
+
 DEFINES += BUILDING_QT__ BUILDING_JavaScriptCore BUILDING_WTF
 
 DEFINES += BUILDING_QT__ BUILDING_JavaScriptCore BUILDING_WTF
 
-win32-* {
-    LIBS += -lwinmm
-}
 contains(JAVASCRIPTCORE_JIT,yes) {
     DEFINES+=ENABLE_JIT=1
     DEFINES+=ENABLE_YARR_JIT=1
 contains(JAVASCRIPTCORE_JIT,yes) {
     DEFINES+=ENABLE_JIT=1
     DEFINES+=ENABLE_YARR_JIT=1
@@ -56,176 +62,50 @@ contains(JAVASCRIPTCORE_JIT,no) {
     DEFINES+=ENABLE_YARR=0
 }
 
     DEFINES+=ENABLE_YARR=0
 }
 
-# Rules when JIT enabled (not disabled)
-!contains(DEFINES, ENABLE_JIT=0) {
-    linux*-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,0) {
-        QMAKE_CXXFLAGS += -fno-stack-protector
-        QMAKE_CFLAGS += -fno-stack-protector
-    }
-}
-
 wince* {
     INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/ce-compat
 wince* {
     INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/ce-compat
-    SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.c
     DEFINES += WINCEBASIC
     DEFINES += WINCEBASIC
+
+    INCLUDEPATH += $$PWD/../JavaScriptCore/os-wince
+    INCLUDEPATH += $$PWD/../JavaScriptCore/os-win32
 }
 
 }
 
-include(pcre/pcre.pri)
 
 
-SOURCES += \
-    API/JSBase.cpp \
-    API/JSCallbackConstructor.cpp \
-    API/JSCallbackFunction.cpp \
-    API/JSCallbackObject.cpp \
-    API/JSClassRef.cpp \
-    API/JSContextRef.cpp \
-    API/JSObjectRef.cpp \
-    API/JSStringRef.cpp \
-    API/JSValueRef.cpp \
-    API/OpaqueJSString.cpp \
-    assembler/ARMAssembler.cpp \
-    assembler/MacroAssemblerARM.cpp \
-    bytecode/CodeBlock.cpp \
-    bytecode/JumpTable.cpp \
-    bytecode/Opcode.cpp \
-    bytecode/SamplingTool.cpp \
-    bytecode/StructureStubInfo.cpp \
-    bytecompiler/BytecodeGenerator.cpp \
-    bytecompiler/NodesCodegen.cpp \
-    debugger/DebuggerActivation.cpp \
-    debugger/DebuggerCallFrame.cpp \
-    debugger/Debugger.cpp \
-    interpreter/CallFrame.cpp \
-    interpreter/Interpreter.cpp \
-    interpreter/RegisterFile.cpp \
-    jit/ExecutableAllocatorPosix.cpp \
-    jit/ExecutableAllocatorSymbian.cpp \
-    jit/ExecutableAllocatorWin.cpp \
-    jit/ExecutableAllocator.cpp \
-    jit/JITArithmetic.cpp \
-    jit/JITCall.cpp \
-    jit/JIT.cpp \
-    jit/JITOpcodes.cpp \
-    jit/JITPropertyAccess.cpp \
-    jit/JITStubs.cpp \
-    parser/Lexer.cpp \
-    parser/Nodes.cpp \
-    parser/ParserArena.cpp \
-    parser/Parser.cpp \
-    profiler/Profile.cpp \
-    profiler/ProfileGenerator.cpp \
-    profiler/ProfileNode.cpp \
-    profiler/Profiler.cpp \
-    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/CommonIdentifiers.cpp \
-    runtime/Completion.cpp \
-    runtime/ConstructData.cpp \
-    runtime/DateConstructor.cpp \
-    runtime/DateConversion.cpp \
-    runtime/DateInstance.cpp \
-    runtime/DatePrototype.cpp \
-    runtime/ErrorConstructor.cpp \
-    runtime/Error.cpp \
-    runtime/ErrorInstance.cpp \
-    runtime/ErrorPrototype.cpp \
-    runtime/ExceptionHelpers.cpp \
-    runtime/Executable.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/JSAPIValueWrapper.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/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/MarkStackPosix.cpp \
-    runtime/MarkStackSymbian.cpp \
-    runtime/MarkStackWin.cpp \
-    runtime/MarkStack.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/PropertyDescriptor.cpp \
-    runtime/PropertyNameArray.cpp \
-    runtime/PropertySlot.cpp \
-    runtime/PrototypeFunction.cpp \
-    runtime/RegExpConstructor.cpp \
-    runtime/RegExp.cpp \
-    runtime/RegExpObject.cpp \
-    runtime/RegExpPrototype.cpp \
-    runtime/ScopeChain.cpp \
-    runtime/SmallStrings.cpp \
-    runtime/StringConstructor.cpp \
-    runtime/StringObject.cpp \
-    runtime/StringPrototype.cpp \
-    runtime/StructureChain.cpp \
-    runtime/Structure.cpp \
-    runtime/TimeoutChecker.cpp \
-    runtime/UString.cpp \
-    runtime/UStringImpl.cpp \
-    wtf/Assertions.cpp \
-    wtf/ByteArray.cpp \
-    wtf/CurrentTime.cpp \
-    wtf/DateMath.cpp \
-    wtf/dtoa.cpp \
-    wtf/FastMalloc.cpp \
-    wtf/HashTable.cpp \
-    wtf/MainThread.cpp \
-    wtf/qt/MainThreadQt.cpp \
-    wtf/qt/ThreadingQt.cpp \
-    wtf/RandomNumber.cpp \
-    wtf/RefCountedLeakCounter.cpp \
-    wtf/ThreadingNone.cpp \
-    wtf/Threading.cpp \
-    wtf/TypeTraits.cpp \
-    wtf/unicode/CollatorDefault.cpp \
-    wtf/unicode/icu/CollatorICU.cpp \
-    wtf/unicode/UTF8.cpp \
-    yarr/RegexCompiler.cpp \
-    yarr/RegexInterpreter.cpp \
-    yarr/RegexJIT.cpp
+defineTest(addJavaScriptCoreLib) {
+    # Argument is the relative path to JavaScriptCore.pro's qmake output
+    pathToJavaScriptCoreOutput = $$ARGS/$$JAVASCRIPTCORE_DESTDIR
 
 
-# Generated files, simply list them for JavaScriptCore
-SOURCES += \
-    $${JSC_GENERATED_SOURCES_DIR}/Grammar.cpp
+    win32-msvc*|wince* {
+        LIBS += -L$$pathToJavaScriptCoreOutput
+        LIBS += -l$$JAVASCRIPTCORE_TARGET
+        POST_TARGETDEPS += $${pathToJavaScriptCoreOutput}$${QMAKE_DIR_SEP}$${JAVASCRIPTCORE_TARGET}.lib
+    } else:symbian {
+        LIBS += -l$${JAVASCRIPTCORE_TARGET}.lib
+        # The default symbian build system does not use library paths at all. However when building with
+        # qmake's symbian makespec that uses Makefiles
+        QMAKE_LIBDIR += $$pathToJavaScriptCoreOutput
+        POST_TARGETDEPS += $${pathToJavaScriptCoreOutput}$${QMAKE_DIR_SEP}$${JAVASCRIPTCORE_TARGET}.lib
+    } else {
+        # Make sure jscore will be early in the list of libraries to workaround a bug in MinGW
+        # that can't resolve symbols from QtCore if libjscore comes after.
+        QMAKE_LIBDIR = $$pathToJavaScriptCoreOutput $$QMAKE_LIBDIR
+        LIBS += -l$$JAVASCRIPTCORE_TARGET
+        POST_TARGETDEPS += $${pathToJavaScriptCoreOutput}$${QMAKE_DIR_SEP}lib$${JAVASCRIPTCORE_TARGET}.a
+    }
 
 
-!contains(DEFINES, USE_SYSTEM_MALLOC) {
-    SOURCES += wtf/TCSystemAlloc.cpp
-}
+    win32-* {
+        LIBS += -lwinmm
+    }
+
+    # The following line is to prevent qmake from adding jscore to libQtWebKit's prl dependencies.
+    # The compromise we have to accept by disabling explicitlib is to drop support to link QtWebKit and QtScript
+    # statically in applications (which isn't used often because, among other things, of licensing obstacles).
+    CONFIG -= explicitlib
 
 
+    export(QMAKE_LIBDIR)
+    export(LIBS)
+    export(POST_TARGETDEPS)
+    export(CONFIG)
+
+    return(true)
+}
index 0d6becb2de21ab4a73c97ae758968a3772fcb2a2..8b0a0efa1123c092c9e2da9db70d518f4347e21c 100644 (file)
@@ -1,48 +1,46 @@
 # JavaScriptCore - qmake build info
 CONFIG += building-libs
 include($$PWD/../WebKit.pri)
 # JavaScriptCore - qmake build info
 CONFIG += building-libs
 include($$PWD/../WebKit.pri)
+include(JavaScriptCore.pri)
 
 TEMPLATE = lib
 CONFIG += staticlib
 
 TEMPLATE = lib
 CONFIG += staticlib
-TARGET = JavaScriptCore
+# Don't use JavaScriptCore as the target name. qmake would create a JavaScriptCore.vcproj for msvc
+# which already exists as a directory
+TARGET = $$JAVASCRIPTCORE_TARGET
+DESTDIR = $$JAVASCRIPTCORE_DESTDIR
+QT += core
+QT -= gui
 
 CONFIG += depend_includepath
 
 contains(QT_CONFIG, embedded):CONFIG += embedded
 
 CONFIG(QTDIR_build) {
 
 CONFIG += depend_includepath
 
 contains(QT_CONFIG, embedded):CONFIG += embedded
 
 CONFIG(QTDIR_build) {
-    GENERATED_SOURCES_DIR = $$PWD/generated
-    OLDDESTDIR = $$DESTDIR
-    include($$QT_SOURCE_TREE/src/qbase.pri)
-    INSTALLS =
-    DESTDIR = $$OLDDESTDIR
-    DEFINES *= NDEBUG
-}
-
-isEmpty(GENERATED_SOURCES_DIR):GENERATED_SOURCES_DIR = tmp
-GENERATED_SOURCES_DIR_SLASH = $${GENERATED_SOURCES_DIR}$${QMAKE_DIR_SEP}
-
-INCLUDEPATH += $$GENERATED_SOURCES_DIR
-
-!CONFIG(QTDIR_build) {
+    # Make sure we compile both debug and release on mac when inside Qt.
+    # This line was extracted from qbase.pri instead of including the whole file
+    win32|mac:!macx-xcode:CONFIG += debug_and_release
+} else {
     CONFIG(debug, debug|release) {
         OBJECTS_DIR = obj/debug
     } else { # Release
         OBJECTS_DIR = obj/release
     }
     CONFIG(debug, debug|release) {
         OBJECTS_DIR = obj/debug
     } else { # Release
         OBJECTS_DIR = obj/release
     }
+    # Make sure that build_all follows the build_all config in WebCore
+    mac:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework):!build_pass:CONFIG += build_all
 }
 
 }
 
-CONFIG(release):!CONFIG(QTDIR_build) {
-    contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
-    unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions
-}
-
-linux-*: DEFINES += HAVE_STDINT_H
-freebsd-*: DEFINES += HAVE_PTHREAD_NP_H
-
-DEFINES += BUILD_WEBKIT
+# WebCore adds these config only when in a standalone build.
+# qbase.pri takes care of that when in a QTDIR_build
+# Here we add the config for both cases since we don't include qbase.pri
+contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
+unix:contains(QT_CONFIG, reduce_relocations):CONFIG += bsymbolic_functions
 
 
-win32-*: DEFINES += _HAS_TR1=0
+CONFIG(QTDIR_build) {
+    # Remove the following 2 lines if you want debug information in JavaScriptCore
+    CONFIG -= separate_debug_info
+    CONFIG += no_debug_info
+}
 
 # Pick up 3rdparty libraries from INCLUDE/LIB just like with MSVC
 win32-g++ {
 
 # Pick up 3rdparty libraries from INCLUDE/LIB just like with MSVC
 win32-g++ {
@@ -52,11 +50,194 @@ win32-g++ {
     QMAKE_LIBDIR_POST += $$split(TMPPATH,";")
 }
 
     QMAKE_LIBDIR_POST += $$split(TMPPATH,";")
 }
 
-DEFINES += WTF_CHANGES=1
+*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2
+*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3
 
 
-include(JavaScriptCore.pri)
+# Rules when JIT enabled (not disabled)
+!contains(DEFINES, ENABLE_JIT=0) {
+    linux*-g++*:greaterThan(QT_GCC_MAJOR_VERSION,3):greaterThan(QT_GCC_MINOR_VERSION,0) {
+        QMAKE_CXXFLAGS += -fno-stack-protector
+        QMAKE_CFLAGS += -fno-stack-protector
+    }
+}
 
 
-QMAKE_EXTRA_TARGETS += generated_files
+wince* {
+    SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.c
+}
 
 
-*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2
-*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3
+include(pcre/pcre.pri)
+
+SOURCES += \
+    API/JSBase.cpp \
+    API/JSCallbackConstructor.cpp \
+    API/JSCallbackFunction.cpp \
+    API/JSCallbackObject.cpp \
+    API/JSClassRef.cpp \
+    API/JSContextRef.cpp \
+    API/JSObjectRef.cpp \
+    API/JSStringRef.cpp \
+    API/JSValueRef.cpp \
+    API/OpaqueJSString.cpp \
+    assembler/ARMAssembler.cpp \
+    assembler/MacroAssemblerARM.cpp \
+    bytecode/CodeBlock.cpp \
+    bytecode/JumpTable.cpp \
+    bytecode/Opcode.cpp \
+    bytecode/SamplingTool.cpp \
+    bytecode/StructureStubInfo.cpp \
+    bytecompiler/BytecodeGenerator.cpp \
+    bytecompiler/NodesCodegen.cpp \
+    debugger/DebuggerActivation.cpp \
+    debugger/DebuggerCallFrame.cpp \
+    debugger/Debugger.cpp \
+    interpreter/CallFrame.cpp \
+    interpreter/Interpreter.cpp \
+    interpreter/RegisterFile.cpp \
+    jit/ExecutableAllocatorFixedVMPool.cpp \
+    jit/ExecutableAllocatorPosix.cpp \
+    jit/ExecutableAllocatorSymbian.cpp \
+    jit/ExecutableAllocatorWin.cpp \
+    jit/ExecutableAllocator.cpp \
+    jit/JITArithmetic.cpp \
+    jit/JITArithmetic32_64.cpp \
+    jit/JITCall.cpp \
+    jit/JIT.cpp \
+    jit/JITOpcodes.cpp \
+    jit/JITOpcodes32_64.cpp \
+    jit/JITPropertyAccess.cpp \
+    jit/JITPropertyAccess32_64.cpp \
+    jit/JITStubs.cpp \
+    jit/ThunkGenerators.cpp \
+    parser/Lexer.cpp \
+    parser/Nodes.cpp \
+    parser/ParserArena.cpp \
+    parser/Parser.cpp \
+    profiler/Profile.cpp \
+    profiler/ProfileGenerator.cpp \
+    profiler/ProfileNode.cpp \
+    profiler/Profiler.cpp \
+    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/CommonIdentifiers.cpp \
+    runtime/Completion.cpp \
+    runtime/ConstructData.cpp \
+    runtime/DateConstructor.cpp \
+    runtime/DateConversion.cpp \
+    runtime/DateInstance.cpp \
+    runtime/DatePrototype.cpp \
+    runtime/ErrorConstructor.cpp \
+    runtime/Error.cpp \
+    runtime/ErrorInstance.cpp \
+    runtime/ErrorPrototype.cpp \
+    runtime/ExceptionHelpers.cpp \
+    runtime/Executable.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/JSAPIValueWrapper.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/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/MarkStackPosix.cpp \
+    runtime/MarkStackSymbian.cpp \
+    runtime/MarkStackWin.cpp \
+    runtime/MarkStack.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/PropertyDescriptor.cpp \
+    runtime/PropertyNameArray.cpp \
+    runtime/PropertySlot.cpp \
+    runtime/PrototypeFunction.cpp \
+    runtime/RegExpConstructor.cpp \
+    runtime/RegExp.cpp \
+    runtime/RegExpObject.cpp \
+    runtime/RegExpPrototype.cpp \
+    runtime/RegExpCache.cpp \
+    runtime/RopeImpl.cpp \
+    runtime/ScopeChain.cpp \
+    runtime/SmallStrings.cpp \
+    runtime/StringConstructor.cpp \
+    runtime/StringObject.cpp \
+    runtime/StringPrototype.cpp \
+    runtime/StructureChain.cpp \
+    runtime/Structure.cpp \
+    runtime/TimeoutChecker.cpp \
+    runtime/UString.cpp \
+    wtf/Assertions.cpp \
+    wtf/ByteArray.cpp \
+    wtf/CurrentTime.cpp \
+    wtf/DateMath.cpp \
+    wtf/dtoa.cpp \
+    wtf/FastMalloc.cpp \
+    wtf/HashTable.cpp \
+    wtf/MD5.cpp \
+    wtf/MainThread.cpp \
+    wtf/qt/MainThreadQt.cpp \
+    wtf/qt/StringQt.cpp \
+    wtf/qt/ThreadingQt.cpp \
+    wtf/RandomNumber.cpp \
+    wtf/RefCountedLeakCounter.cpp \
+    wtf/symbian/BlockAllocatorSymbian.cpp \
+    wtf/ThreadingNone.cpp \
+    wtf/Threading.cpp \
+    wtf/TypeTraits.cpp \
+    wtf/WTFThreadData.cpp \
+    wtf/text/AtomicString.cpp \
+    wtf/text/CString.cpp \
+    wtf/text/StringImpl.cpp \
+    wtf/text/StringStatics.cpp \
+    wtf/text/WTFString.cpp \
+    wtf/unicode/CollatorDefault.cpp \
+    wtf/unicode/icu/CollatorICU.cpp \
+    wtf/unicode/UTF8.cpp \
+    yarr/RegexCompiler.cpp \
+    yarr/RegexInterpreter.cpp \
+    yarr/RegexJIT.cpp
+
+# Generated files, simply list them for JavaScriptCore
+SOURCES += \
+    $${JSC_GENERATED_SOURCES_DIR}/Grammar.cpp
+
+!contains(DEFINES, USE_SYSTEM_MALLOC) {
+    SOURCES += wtf/TCSystemAlloc.cpp
+}
+
+# Disable C++0x mode in JSC for those who enabled it in their Qt's mkspec
+*-g++*:QMAKE_CXXFLAGS -= -std=c++0x -std=gnu++0x
index 6dd2b87ff6e0e9a78845dad10df63d9d4d820f05..a181b7e982f4a4eaa7c68e78a0b94197a7b06f3c 100644 (file)
@@ -262,28 +262,29 @@ ARMWord ARMAssembler::encodeComplexImm(ARMWord imm, int dest)
 
 // Memory load/store helpers
 
 
 // Memory load/store helpers
 
-void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset)
+void ARMAssembler::dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset, bool bytes)
 {
 {
+    ARMWord transferFlag = bytes ? DT_BYTE : 0;
     if (offset >= 0) {
         if (offset <= 0xfff)
     if (offset >= 0) {
         if (offset <= 0xfff)
-            dtr_u(isLoad, srcDst, base, offset);
+            dtr_u(isLoad, srcDst, base, offset | transferFlag);
         else if (offset <= 0xfffff) {
             add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
         else if (offset <= 0xfffff) {
             add_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
-            dtr_u(isLoad, srcDst, ARMRegisters::S0, offset & 0xfff);
+            dtr_u(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag);
         } else {
             ARMWord reg = getImm(offset, ARMRegisters::S0);
         } else {
             ARMWord reg = getImm(offset, ARMRegisters::S0);
-            dtr_ur(isLoad, srcDst, base, reg);
+            dtr_ur(isLoad, srcDst, base, reg | transferFlag);
         }
     } else {
         offset = -offset;
         if (offset <= 0xfff)
         }
     } else {
         offset = -offset;
         if (offset <= 0xfff)
-            dtr_d(isLoad, srcDst, base, offset);
+            dtr_d(isLoad, srcDst, base, offset | transferFlag);
         else if (offset <= 0xfffff) {
             sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
         else if (offset <= 0xfffff) {
             sub_r(ARMRegisters::S0, base, OP2_IMM | (offset >> 12) | (10 << 8));
-            dtr_d(isLoad, srcDst, ARMRegisters::S0, offset & 0xfff);
+            dtr_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag);
         } else {
             ARMWord reg = getImm(offset, ARMRegisters::S0);
         } else {
             ARMWord reg = getImm(offset, ARMRegisters::S0);
-            dtr_dr(isLoad, srcDst, base, reg);
+            dtr_dr(isLoad, srcDst, base, reg | transferFlag);
         }
     }
 }
         }
     }
 }
@@ -356,7 +357,7 @@ void* ARMAssembler::executableCopy(ExecutablePool* allocator)
         int pos = (*iter) & (~0x1);
         ARMWord* ldrAddr = reinterpret_cast<ARMWord*>(data + pos);
         ARMWord* addr = getLdrImmAddress(ldrAddr);
         int pos = (*iter) & (~0x1);
         ARMWord* ldrAddr = reinterpret_cast<ARMWord*>(data + pos);
         ARMWord* addr = getLdrImmAddress(ldrAddr);
-        if (*addr != 0xffffffff) {
+        if (*addr != InvalidBranchTarget) {
             if (!(*iter & 1)) {
                 int diff = reinterpret_cast<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetching);
 
             if (!(*iter & 1)) {
                 int diff = reinterpret_cast<ARMWord*>(data + *addr) - (ldrAddr + DefaultPrefetching);
 
index 6967b37a81ec896ac5cf7afdfc8ddd7e32018a9a..2ca0949803079ba7bb4864bab1d29c6aa4722ad5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2009 University of Szeged
+ * Copyright (C) 2009, 2010 University of Szeged
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,8 +27,6 @@
 #ifndef ARMAssembler_h
 #define ARMAssembler_h
 
 #ifndef ARMAssembler_h
 #define ARMAssembler_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
 
 #include "AssemblerBufferWithConstantPool.h"
 #if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
 
 #include "AssemblerBufferWithConstantPool.h"
@@ -125,6 +123,7 @@ namespace JSC {
             FSUBD = 0x0e300b40,
             FMULD = 0x0e200b00,
             FCMPD = 0x0eb40b40,
             FSUBD = 0x0e300b40,
             FMULD = 0x0e200b00,
             FCMPD = 0x0eb40b40,
+            FSQRTD = 0x0eb10bc0,
             DTR = 0x05000000,
             LDRH = 0x00100090,
             STRH = 0x00000090,
             DTR = 0x05000000,
             LDRH = 0x00100090,
             STRH = 0x00000090,
@@ -133,6 +132,9 @@ namespace JSC {
             FDTR = 0x0d000b00,
             B = 0x0a000000,
             BL = 0x0b000000,
             FDTR = 0x0d000b00,
             B = 0x0a000000,
             BL = 0x0b000000,
+#if WTF_ARM_ARCH_AT_LEAST(5) || defined(__ARM_ARCH_4T__)
+            BX = 0x012fff10,
+#endif
             FMSR = 0x0e000a10,
             FMRS = 0x0e100a10,
             FSITOD = 0x0eb80bc0,
             FMSR = 0x0e000a10,
             FMRS = 0x0e100a10,
             FSITOD = 0x0eb80bc0,
@@ -141,6 +143,7 @@ namespace JSC {
 #if WTF_ARM_ARCH_AT_LEAST(5)
             CLZ = 0x016f0f10,
             BKPT = 0xe120070,
 #if WTF_ARM_ARCH_AT_LEAST(5)
             CLZ = 0x016f0f10,
             BKPT = 0xe120070,
+            BLX = 0x012fff30,
 #endif
 #if WTF_ARM_ARCH_AT_LEAST(7)
             MOVW = 0x03000000,
 #endif
 #if WTF_ARM_ARCH_AT_LEAST(7)
             MOVW = 0x03000000,
@@ -155,6 +158,7 @@ namespace JSC {
             SET_CC = (1 << 20),
             OP2_OFSREG = (1 << 25),
             DT_UP = (1 << 23),
             SET_CC = (1 << 20),
             OP2_OFSREG = (1 << 25),
             DT_UP = (1 << 23),
+            DT_BYTE = (1 << 22),
             DT_WB = (1 << 21),
             // This flag is inlcuded in LDR and STR
             DT_PRE = (1 << 24),
             DT_WB = (1 << 21),
             // This flag is inlcuded in LDR and STR
             DT_PRE = (1 << 24),
@@ -183,6 +187,7 @@ namespace JSC {
         };
 
         static const ARMWord INVALID_IMM = 0xf0000000;
         };
 
         static const ARMWord INVALID_IMM = 0xf0000000;
+        static const ARMWord InvalidBranchTarget = 0xffffffff;
         static const int DefaultPrefetching = 2;
 
         class JmpSrc {
         static const int DefaultPrefetching = 2;
 
         class JmpSrc {
@@ -422,6 +427,11 @@ namespace JSC {
             emitInst(static_cast<ARMWord>(cc) | FCMPD, dd, 0, dm);
         }
 
             emitInst(static_cast<ARMWord>(cc) | FCMPD, dd, 0, dm);
         }
 
+        void fsqrtd_r(int dd, int dm, Condition cc = AL)
+        {
+            emitInst(static_cast<ARMWord>(cc) | FSQRTD, dd, 0, dm);
+        }
+
         void ldr_imm(int rd, ARMWord imm, Condition cc = AL)
         {
             m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | DTR | DT_LOAD | DT_UP | RN(ARMRegisters::pc) | RD(rd), imm, true);
         void ldr_imm(int rd, ARMWord imm, Condition cc = AL)
         {
             m_buffer.putIntWithConstantInt(static_cast<ARMWord>(cc) | DTR | DT_LOAD | DT_UP | RN(ARMRegisters::pc) | RD(rd), imm, true);
@@ -548,6 +558,30 @@ namespace JSC {
 #endif
         }
 
 #endif
         }
 
+        void bx(int rm, Condition cc = AL)
+        {
+#if WTF_ARM_ARCH_AT_LEAST(5) || defined(__ARM_ARCH_4T__)
+            emitInst(static_cast<ARMWord>(cc) | BX, 0, 0, RM(rm));
+#else
+            mov_r(ARMRegisters::pc, RM(rm), cc);
+#endif
+        }
+
+        JmpSrc blx(int rm, Condition cc = AL)
+        {
+#if WTF_ARM_ARCH_AT_LEAST(5)
+            int s = m_buffer.uncheckedSize();
+            emitInst(static_cast<ARMWord>(cc) | BLX, 0, 0, RM(rm));
+#else
+            ASSERT(rm != 14);
+            ensureSpace(2 * sizeof(ARMWord), 0);
+            mov_r(ARMRegisters::lr, ARMRegisters::pc, cc);
+            int s = m_buffer.uncheckedSize();
+            bx(rm, cc);
+#endif
+            return JmpSrc(s);
+        }
+
         static ARMWord lsl(int reg, ARMWord value)
         {
             ASSERT(reg <= ARMRegisters::pc);
         static ARMWord lsl(int reg, ARMWord value)
         {
             ASSERT(reg <= ARMRegisters::pc);
@@ -620,21 +654,34 @@ namespace JSC {
             return label();
         }
 
             return label();
         }
 
-        JmpSrc jmp(Condition cc = AL, int useConstantPool = 0)
+        JmpSrc loadBranchTarget(int rd, Condition cc = AL, int useConstantPool = 0)
         {
             ensureSpace(sizeof(ARMWord), sizeof(ARMWord));
             int s = m_buffer.uncheckedSize();
         {
             ensureSpace(sizeof(ARMWord), sizeof(ARMWord));
             int s = m_buffer.uncheckedSize();
-            ldr_un_imm(ARMRegisters::pc, 0xffffffff, cc);
+            ldr_un_imm(rd, InvalidBranchTarget, cc);
             m_jumps.append(s | (useConstantPool & 0x1));
             return JmpSrc(s);
         }
 
             m_jumps.append(s | (useConstantPool & 0x1));
             return JmpSrc(s);
         }
 
+        JmpSrc jmp(Condition cc = AL, int useConstantPool = 0)
+        {
+            return loadBranchTarget(ARMRegisters::pc, cc, useConstantPool);
+        }
+
         void* executableCopy(ExecutablePool* allocator);
 
         // Patching helpers
 
         static ARMWord* getLdrImmAddress(ARMWord* insn)
         {
         void* executableCopy(ExecutablePool* allocator);
 
         // Patching helpers
 
         static ARMWord* getLdrImmAddress(ARMWord* insn)
         {
+#if WTF_ARM_ARCH_AT_LEAST(5)
+            // Check for call
+            if ((*insn & 0x0f7f0000) != 0x051f0000) {
+                // Must be BLX
+                ASSERT((*insn & 0x012fff30) == 0x012fff30);
+                insn--;
+            }
+#endif
             // Must be an ldr ..., [pc +/- imm]
             ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
 
             // Must be an ldr ..., [pc +/- imm]
             ASSERT((*insn & 0x0f7f0000) == 0x051f0000);
 
@@ -780,7 +827,7 @@ namespace JSC {
 
         // Memory load/store helpers
 
 
         // Memory load/store helpers
 
-        void dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset);
+        void dataTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, int32_t offset, bool bytes = false);
         void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset);
         void doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset);
 
         void baseIndexTransfer32(bool isLoad, RegisterID srcDst, RegisterID base, RegisterID index, int scale, int32_t offset);
         void doubleTransfer(bool isLoad, FPRegisterID srcDst, RegisterID base, int32_t offset);
 
index 4e394b2069246ade02dd8adac9b197c072939cc9..2faa3a6102acc3197a9e2ad4e48f9a425607e01a 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009 Apple Inc. All rights reserved.
 /*
  * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 University of Szeged
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +27,6 @@
 #ifndef ARMAssembler_h
 #define ARMAssembler_h
 
 #ifndef ARMAssembler_h
 #define ARMAssembler_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
 
 #include "AssemblerBuffer.h"
 #if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
 
 #include "AssemblerBuffer.h"
@@ -57,107 +56,122 @@ namespace ARMRegisters {
         r15, pc = r15,
     } RegisterID;
 
         r15, pc = r15,
     } RegisterID;
 
-    // s0 == d0 == q0
-    // s4 == d2 == q1
-    // etc
     typedef enum {
     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;
+        s0,
+        s1,
+        s2,
+        s3,
+        s4,
+        s5,
+        s6,
+        s7,
+        s8,
+        s9,
+        s10,
+        s11,
+        s12,
+        s13,
+        s14,
+        s15,
+        s16,
+        s17,
+        s18,
+        s19,
+        s20,
+        s21,
+        s22,
+        s23,
+        s24,
+        s25,
+        s26,
+        s27,
+        s28,
+        s29,
+        s30,
+        s31,
+    } FPSingleRegisterID;
+
+    typedef enum {
+        d0,
+        d1,
+        d2,
+        d3,
+        d4,
+        d5,
+        d6,
+        d7,
+        d8,
+        d9,
+        d10,
+        d11,
+        d12,
+        d13,
+        d14,
+        d15,
+        d16,
+        d17,
+        d18,
+        d19,
+        d20,
+        d21,
+        d22,
+        d23,
+        d24,
+        d25,
+        d26,
+        d27,
+        d28,
+        d29,
+        d30,
+        d31,
+    } FPDoubleRegisterID;
+
+    typedef enum {
+        q0,
+        q1,
+        q2,
+        q3,
+        q4,
+        q5,
+        q6,
+        q7,
+        q8,
+        q9,
+        q10,
+        q11,
+        q12,
+        q13,
+        q14,
+        q15,
+        q16,
+        q17,
+        q18,
+        q19,
+        q20,
+        q21,
+        q22,
+        q23,
+        q24,
+        q25,
+        q26,
+        q27,
+        q28,
+        q29,
+        q30,
+        q31,
+    } FPQuadRegisterID;
+
+    inline FPSingleRegisterID asSingle(FPDoubleRegisterID reg)
+    {
+        ASSERT(reg < d16);
+        return (FPSingleRegisterID)(reg << 1);
+    }
+
+    inline FPDoubleRegisterID asDouble(FPSingleRegisterID reg)
+    {
+        ASSERT(!(reg & 1));
+        return (FPDoubleRegisterID)(reg >> 1);
+    }
 }
 
 class ARMv7Assembler;
 }
 
 class ARMv7Assembler;
@@ -355,6 +369,39 @@ private:
     ThumbImmediateValue m_value;
 };
 
     ThumbImmediateValue m_value;
 };
 
+class VFPImmediate {
+public:
+    VFPImmediate(double d)
+        : m_value(-1)
+    {
+        union {
+            uint64_t i;
+            double d;
+        } u;
+
+        u.d = d;
+
+        int sign = static_cast<int>(u.i >> 63);
+        int exponent = static_cast<int>(u.i >> 52) & 0x7ff;
+        uint64_t mantissa = u.i & 0x000fffffffffffffull;
+
+        if ((exponent >= 0x3fc) && (exponent <= 0x403) && !(mantissa & 0x0000ffffffffffffull))
+            m_value = (sign << 7) | ((exponent & 7) << 4) | (int)(mantissa >> 48);
+    }
+
+    bool isValid()
+    {
+        return m_value != -1;
+    }
+    
+    uint8_t value()
+    {
+        return (uint8_t)m_value;
+    }
+
+private:
+    int m_value;
+};
 
 typedef enum {
     SRType_LSL,
 
 typedef enum {
     SRType_LSL,
@@ -399,17 +446,6 @@ private:
 };
 
 
 };
 
 
-/*
-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:
     ~ARMv7Assembler()
 class ARMv7Assembler {
 public:
     ~ARMv7Assembler()
@@ -418,7 +454,9 @@ public:
     }
 
     typedef ARMRegisters::RegisterID RegisterID;
     }
 
     typedef ARMRegisters::RegisterID RegisterID;
-    typedef ARMRegisters::FPRegisterID FPRegisterID;
+    typedef ARMRegisters::FPSingleRegisterID FPSingleRegisterID;
+    typedef ARMRegisters::FPDoubleRegisterID FPDoubleRegisterID;
+    typedef ARMRegisters::FPQuadRegisterID FPQuadRegisterID;
 
     // (HS, LO, HI, LS) -> (AE, B, A, BE)
     // (VS, VC) -> (O, NO)
 
     // (HS, LO, HI, LS) -> (AE, B, A, BE)
     // (VS, VC) -> (O, NO)
@@ -504,53 +542,16 @@ private:
         return (reg == ARMRegisters::sp) || (reg == ARMRegisters::pc);
     }
 
         return (reg == ARMRegisters::sp) || (reg == ARMRegisters::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 singleRegisterMask(FPSingleRegisterID rdNum, 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 rdMask = (rdNum >> 1) << highBitsShift;
         if (rdNum & 1)
             rdMask |= 1 << lowBitShift;
         return rdMask;
     }
 
-    uint32_t doubleRegisterMask(FPRegisterID rd, int highBitShift, int lowBitsShift)
+    uint32_t doubleRegisterMask(FPDoubleRegisterID rdNum, int highBitShift, int lowBitsShift)
     {
     {
-        uint32_t rdNum = doubleRegisterNum(rd);
         uint32_t rdMask = (rdNum & 0xf) << lowBitsShift;
         if (rdNum & 16)
             rdMask |= 1 << highBitShift;
         uint32_t rdMask = (rdNum & 0xf) << lowBitsShift;
         if (rdNum & 16)
             rdMask |= 1 << highBitShift;
@@ -559,22 +560,17 @@ private:
 
     typedef enum {
         OP_ADD_reg_T1       = 0x1800,
 
     typedef enum {
         OP_ADD_reg_T1       = 0x1800,
-        OP_ADD_S_reg_T1     = 0x1800,
         OP_SUB_reg_T1       = 0x1A00,
         OP_SUB_reg_T1       = 0x1A00,
-        OP_SUB_S_reg_T1     = 0x1A00,
         OP_ADD_imm_T1       = 0x1C00,
         OP_ADD_imm_T1       = 0x1C00,
-        OP_ADD_S_imm_T1     = 0x1C00,
         OP_SUB_imm_T1       = 0x1E00,
         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_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_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_AND_reg_T1       = 0x4000,
         OP_EOR_reg_T1       = 0x4040,
         OP_TST_reg_T1       = 0x4200,
+        OP_RSB_imm_T1       = 0x4240,
         OP_CMP_reg_T1       = 0x4280,
         OP_ORR_reg_T1       = 0x4300,
         OP_MVN_reg_T1       = 0x43C0,
         OP_CMP_reg_T1       = 0x4280,
         OP_ORR_reg_T1       = 0x4300,
         OP_MVN_reg_T1       = 0x43C0,
@@ -582,11 +578,13 @@ private:
         OP_MOV_reg_T1       = 0x4600,
         OP_BLX              = 0x4700,
         OP_BX               = 0x4700,
         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_reg_T1       = 0x5000,
         OP_LDR_reg_T1       = 0x5800,
+        OP_LDRH_reg_T1      = 0x5A00,
+        OP_LDRB_reg_T1      = 0x5C00,
         OP_STR_imm_T1       = 0x6000,
         OP_LDR_imm_T1       = 0x6800,
         OP_STR_imm_T1       = 0x6000,
         OP_LDR_imm_T1       = 0x6800,
+        OP_LDRB_imm_T1      = 0x7800,
         OP_LDRH_imm_T1      = 0x8800,
         OP_STR_imm_T2       = 0x9000,
         OP_LDR_imm_T2       = 0x9800,
         OP_LDRH_imm_T1      = 0x8800,
         OP_STR_imm_T2       = 0x9000,
         OP_LDR_imm_T2       = 0x9800,
@@ -602,6 +600,7 @@ private:
         OP_AND_reg_T2   = 0xEA00,
         OP_TST_reg_T2   = 0xEA10,
         OP_ORR_reg_T2   = 0xEA40,
         OP_AND_reg_T2   = 0xEA00,
         OP_TST_reg_T2   = 0xEA10,
         OP_ORR_reg_T2   = 0xEA40,
+        OP_ORR_S_reg_T2 = 0xEA50,
         OP_ASR_imm_T1   = 0xEA4F,
         OP_LSL_imm_T1   = 0xEA4F,
         OP_LSR_imm_T1   = 0xEA4F,
         OP_ASR_imm_T1   = 0xEA4F,
         OP_LSL_imm_T1   = 0xEA4F,
         OP_LSR_imm_T1   = 0xEA4F,
@@ -613,6 +612,18 @@ private:
         OP_SUB_reg_T2   = 0xEBA0,
         OP_SUB_S_reg_T2 = 0xEBB0,
         OP_CMP_reg_T2   = 0xEBB0,
         OP_SUB_reg_T2   = 0xEBA0,
         OP_SUB_S_reg_T2 = 0xEBB0,
         OP_CMP_reg_T2   = 0xEBB0,
+        OP_VSTR         = 0xED00,
+        OP_VLDR         = 0xED10,
+        OP_VMOV_StoC    = 0xEE00,
+        OP_VMOV_CtoS    = 0xEE10,
+        OP_VMUL_T2      = 0xEE20,
+        OP_VADD_T2      = 0xEE30,
+        OP_VSUB_T2      = 0xEE30,
+        OP_VDIV         = 0xEE80,
+        OP_VCMP_T1      = 0xEEB0,
+        OP_VCVT_FPIVFP  = 0xEEB0,
+        OP_VMOV_IMM_T2  = 0xEEB0,
+        OP_VMRS         = 0xEEB0,
         OP_B_T4a        = 0xF000,
         OP_AND_imm_T1   = 0xF000,
         OP_TST_imm      = 0xF010,
         OP_B_T4a        = 0xF000,
         OP_AND_imm_T1   = 0xF000,
         OP_TST_imm      = 0xF010,
@@ -626,17 +637,21 @@ private:
         OP_SUB_imm_T3   = 0xF1A0,
         OP_SUB_S_imm_T3 = 0xF1B0,
         OP_CMP_imm_T2   = 0xF1B0,
         OP_SUB_imm_T3   = 0xF1A0,
         OP_SUB_S_imm_T3 = 0xF1B0,
         OP_CMP_imm_T2   = 0xF1B0,
+        OP_RSB_imm_T2   = 0xF1C0,
         OP_ADD_imm_T4   = 0xF200,
         OP_MOV_imm_T3   = 0xF240,
         OP_SUB_imm_T4   = 0xF2A0,
         OP_MOVT         = 0xF2C0,
         OP_NOP_T2a      = 0xF3AF,
         OP_ADD_imm_T4   = 0xF200,
         OP_MOV_imm_T3   = 0xF240,
         OP_SUB_imm_T4   = 0xF2A0,
         OP_MOVT         = 0xF2C0,
         OP_NOP_T2a      = 0xF3AF,
+        OP_LDRB_imm_T3  = 0xF810,
+        OP_LDRB_reg_T2  = 0xF810,
         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_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_LDRB_imm_T2  = 0xF890,
         OP_LDRH_imm_T2  = 0xF8B0,
         OP_STR_imm_T3   = 0xF8C0,
         OP_LDR_imm_T3   = 0xF8D0,
         OP_LDRH_imm_T2  = 0xF8B0,
         OP_STR_imm_T3   = 0xF8C0,
         OP_LDR_imm_T3   = 0xF8D0,
@@ -648,8 +663,20 @@ private:
     } OpcodeID1;
 
     typedef enum {
     } OpcodeID1;
 
     typedef enum {
-        OP_B_T4b        = 0x9000,
+        OP_VADD_T2b     = 0x0A00,
+        OP_VDIVb        = 0x0A00,
+        OP_VLDRb        = 0x0A00,
+        OP_VMOV_IMM_T2b = 0x0A00,
+        OP_VMUL_T2b     = 0x0A00,
+        OP_VSTRb        = 0x0A00,
+        OP_VMOV_CtoSb   = 0x0A10,
+        OP_VMOV_StoCb   = 0x0A10,
+        OP_VMRSb        = 0x0A10,
+        OP_VCMP_T1b     = 0x0A40,
+        OP_VCVT_FPIVFPb = 0x0A40,
+        OP_VSUB_T2b     = 0x0A40,
         OP_NOP_T2b      = 0x8000,
         OP_NOP_T2b      = 0x8000,
+        OP_B_T4b        = 0x9000,
     } OpcodeID2;
 
     struct FourFours {
     } OpcodeID2;
 
     struct FourFours {
@@ -780,10 +807,10 @@ public:
 
         if (!((rd | rn) & 8)) {
             if (imm.isUInt3()) {
 
         if (!((rd | rn) & 8)) {
             if (imm.isUInt3()) {
-                m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_S_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
+                m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
                 return;
             } else if ((rd == rn) && imm.isUInt8()) {
                 return;
             } else if ((rd == rn) && imm.isUInt8()) {
-                m_formatter.oneWordOp5Reg3Imm8(OP_ADD_S_imm_T2, rd, imm.getUInt8());
+                m_formatter.oneWordOp5Reg3Imm8(OP_ADD_imm_T2, rd, imm.getUInt8());
                 return;
             }
         }
                 return;
             }
         }
@@ -805,7 +832,7 @@ public:
     void add_S(RegisterID rd, RegisterID rn, RegisterID rm)
     {
         if (!((rd | rn | rm) & 8))
     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);
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_ADD_reg_T1, rm, rn, rd);
         else
             add_S(rd, rn, rm, ShiftTypeAndAmount());
     }
         else
             add_S(rd, rn, rm, ShiftTypeAndAmount());
     }
@@ -1080,6 +1107,52 @@ public:
             m_formatter.twoWordOp12Reg4FourFours(OP_LDRH_reg_T2, rn, FourFours(rt, 0, shift, rm));
     }
 
             m_formatter.twoWordOp12Reg4FourFours(OP_LDRH_reg_T2, rn, FourFours(rt, 0, shift, rm));
     }
 
+    void ldrb(RegisterID rt, RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(rn != ARMRegisters::pc); // LDR (literal)
+        ASSERT(imm.isUInt12());
+
+        if (!((rt | rn) & 8) && imm.isUInt5())
+            m_formatter.oneWordOp5Imm5Reg3Reg3(OP_LDRB_imm_T1, imm.getUInt5(), rn, rt);
+        else
+            m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRB_imm_T2, rn, rt, imm.getUInt12());
+    }
+
+    void ldrb(RegisterID rt, RegisterID rn, int offset, bool index, bool wback)
+    {
+        ASSERT(rt != ARMRegisters::pc);
+        ASSERT(rn != ARMRegisters::pc);
+        ASSERT(index || wback);
+        ASSERT(!wback | (rt != rn));
+
+        bool add = true;
+        if (offset < 0) {
+            add = false;
+            offset = -offset;
+        }
+
+        ASSERT(!(offset & ~0xff));
+
+        offset |= (wback << 8);
+        offset |= (add   << 9);
+        offset |= (index << 10);
+        offset |= (1 << 11);
+
+        m_formatter.twoWordOp12Reg4Reg4Imm12(OP_LDRB_imm_T3, rn, rt, offset);
+    }
+
+    void ldrb(RegisterID rt, RegisterID rn, RegisterID rm, unsigned shift = 0)
+    {
+        ASSERT(rn != ARMRegisters::pc); // LDR (literal)
+        ASSERT(!BadReg(rm));
+        ASSERT(shift <= 3);
+
+        if (!shift && !((rt | rn | rm) & 8))
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_LDRB_reg_T1, rm, rn, rt);
+        else
+            m_formatter.twoWordOp12Reg4FourFours(OP_LDRB_reg_T2, rn, FourFours(rt, 0, shift, rm));
+    }
+
     void lsl(RegisterID rd, RegisterID rm, int32_t shiftAmount)
     {
         ASSERT(!BadReg(rd));
     void lsl(RegisterID rd, RegisterID rm, int32_t shiftAmount)
     {
         ASSERT(!BadReg(rd));
@@ -1169,6 +1242,12 @@ public:
             mvn(rd, rm, ShiftTypeAndAmount());
     }
 
             mvn(rd, rm, ShiftTypeAndAmount());
     }
 
+    void neg(RegisterID rd, RegisterID rm)
+    {
+        ARMThumbImmediate zero = ARMThumbImmediate::makeUInt12(0);
+        sub(rd, zero, rm);
+    }
+
     void orr(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
     {
         ASSERT(!BadReg(rd));
     void orr(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
     {
         ASSERT(!BadReg(rd));
@@ -1195,6 +1274,24 @@ public:
             orr(rd, rn, rm, ShiftTypeAndAmount());
     }
 
             orr(rd, rn, rm, ShiftTypeAndAmount());
     }
 
+    void orr_S(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(!BadReg(rm));
+        m_formatter.twoWordOp12Reg4FourFours(OP_ORR_S_reg_T2, rn, FourFours(shift.hi4(), rd, shift.lo4(), rm));
+    }
+
+    void orr_S(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_S(rd, rn, rm, ShiftTypeAndAmount());
+    }
+
     void ror(RegisterID rd, RegisterID rm, int32_t shiftAmount)
     {
         ASSERT(!BadReg(rd));
     void ror(RegisterID rd, RegisterID rm, int32_t shiftAmount)
     {
         ASSERT(!BadReg(rd));
@@ -1311,6 +1408,19 @@ public:
         }
     }
 
         }
     }
 
+    void sub(RegisterID rd, ARMThumbImmediate imm, RegisterID rn)
+    {
+        ASSERT(rd != ARMRegisters::pc);
+        ASSERT(rn != ARMRegisters::pc);
+        ASSERT(imm.isValid());
+        ASSERT(imm.isUInt12());
+
+        if (!((rd | rn) & 8) && !imm.getUInt12())
+            m_formatter.oneWordOp10Reg3Reg3(OP_RSB_imm_T1, rn, rd);
+        else
+            m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_RSB_imm_T2, rn, rd, imm);
+    }
+
     void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
     {
         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
     void sub(RegisterID rd, RegisterID rn, RegisterID rm, ShiftTypeAndAmount shift)
     {
         ASSERT((rd != ARMRegisters::sp) || (rn == ARMRegisters::sp));
@@ -1343,10 +1453,10 @@ public:
             return;
         } else if (!((rd | rn) & 8)) {
             if (imm.isUInt3()) {
             return;
         } else if (!((rd | rn) & 8)) {
             if (imm.isUInt3()) {
-                m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_S_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
+                m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_imm_T1, (RegisterID)imm.getUInt3(), rn, rd);
                 return;
             } else if ((rd == rn) && imm.isUInt8()) {
                 return;
             } else if ((rd == rn) && imm.isUInt8()) {
-                m_formatter.oneWordOp5Reg3Imm8(OP_SUB_S_imm_T2, rd, imm.getUInt8());
+                m_formatter.oneWordOp5Reg3Imm8(OP_SUB_imm_T2, rd, imm.getUInt8());
                 return;
             }
         }
                 return;
             }
         }
@@ -1368,7 +1478,7 @@ public:
     void sub_S(RegisterID rd, RegisterID rn, RegisterID rm)
     {
         if (!((rd | rn | rm) & 8))
     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);
+            m_formatter.oneWordOp7Reg3Reg3Reg3(OP_SUB_reg_T1, rm, rn, rd);
         else
             sub_S(rd, rn, rm, ShiftTypeAndAmount());
     }
         else
             sub_S(rd, rn, rm, ShiftTypeAndAmount());
     }
@@ -1396,62 +1506,75 @@ public:
             m_formatter.oneWordOp10Reg3Reg3(OP_TST_reg_T1, rm, rn);
     }
 
             m_formatter.oneWordOp10Reg3Reg3(OP_TST_reg_T1, rm, rn);
     }
 
-    void vadd_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm)
+    void vadd_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
     {
     {
-        m_formatter.vfpOp(0x0b00ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));
+        m_formatter.vfpOp(OP_VADD_T2, OP_VADD_T2b, true, rn, rd, rm);
     }
 
     }
 
-    void vcmp_F64(FPRegisterID rd, FPRegisterID rm)
+    void vcmp_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rm)
     {
     {
-        m_formatter.vfpOp(0x0bc0eeb4 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rm, 21, 16));
+        m_formatter.vfpOp(OP_VCMP_T1, OP_VCMP_T1b, true, VFPOperand(4), rd, rm);
     }
 
     }
 
-    void vcvt_F64_S32(FPRegisterID fd, FPRegisterID sm)
+    void vcvt_F64_S32(FPDoubleRegisterID rd, FPSingleRegisterID rm)
     {
     {
-        m_formatter.vfpOp(0x0bc0eeb8 | doubleRegisterMask(fd, 6, 28) | singleRegisterMask(sm, 16, 21));
+        // boolean values are 64bit (toInt, unsigned, roundZero)
+        m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(false, false, false), rd, rm);
     }
 
     }
 
-    void vcvt_S32_F64(FPRegisterID sd, FPRegisterID fm)
+    void vcvtr_S32_F64(FPSingleRegisterID rd, FPDoubleRegisterID rm)
     {
     {
-        m_formatter.vfpOp(0x0bc0eebd | singleRegisterMask(sd, 28, 6) | doubleRegisterMask(fm, 21, 16));
+        // boolean values are 64bit (toInt, unsigned, roundZero)
+        m_formatter.vfpOp(OP_VCVT_FPIVFP, OP_VCVT_FPIVFPb, true, vcvtOp(true, false, true), rd, rm);
     }
 
     }
 
-    void vldr(FPRegisterID rd, RegisterID rn, int32_t imm)
+    void vdiv_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
     {
     {
-        vmem(rd, rn, imm, true);
+        m_formatter.vfpOp(OP_VDIV, OP_VDIVb, true, rn, rd, rm);
     }
 
     }
 
-    void vmov(RegisterID rd, FPRegisterID sn)
+    void vldr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm)
     {
     {
-        m_formatter.vfpOp(0x0a10ee10 | (rd << 28) | singleRegisterMask(sn, 0, 23));
+        m_formatter.vfpMemOp(OP_VLDR, OP_VLDRb, true, rn, rd, imm);
     }
 
     }
 
-    void vmov(FPRegisterID sn, RegisterID rd)
+    void vmov_F64_0(FPDoubleRegisterID rd)
     {
     {
-        m_formatter.vfpOp(0x0a10ee00 | (rd << 28) | singleRegisterMask(sn, 0, 23));
+        m_formatter.vfpOp(OP_VMOV_IMM_T2, OP_VMOV_IMM_T2b, true, VFPOperand(0), rd, VFPOperand(0));
+    }
+
+    void vmov(RegisterID rd, FPSingleRegisterID rn)
+    {
+        ASSERT(!BadReg(rd));
+        m_formatter.vfpOp(OP_VMOV_CtoS, OP_VMOV_CtoSb, false, rn, rd, VFPOperand(0));
     }
 
     }
 
-    // move FPSCR flags to APSR.
-    void vmrs_APSR_nzcv_FPSCR()
+    void vmov(FPSingleRegisterID rd, RegisterID rn)
     {
     {
-        m_formatter.vfpOp(0xfa10eef1);
+        ASSERT(!BadReg(rn));
+        m_formatter.vfpOp(OP_VMOV_StoC, OP_VMOV_StoCb, false, rd, rn, VFPOperand(0));
     }
 
     }
 
-    void vmul_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm)
+    void vmrs(RegisterID reg = ARMRegisters::pc)
     {
     {
-        m_formatter.vfpOp(0x0b00ee20 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));
+        ASSERT(reg != ARMRegisters::sp);
+        m_formatter.vfpOp(OP_VMRS, OP_VMRSb, false, VFPOperand(1), VFPOperand(0x10 | reg), VFPOperand(0));
     }
 
     }
 
-    void vstr(FPRegisterID rd, RegisterID rn, int32_t imm)
+    void vmul_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
     {
     {
-        vmem(rd, rn, imm, false);
+        m_formatter.vfpOp(OP_VMUL_T2, OP_VMUL_T2b, true, rn, rd, rm);
     }
 
     }
 
-    void vsub_F64(FPRegisterID rd, FPRegisterID rn, FPRegisterID rm)
+    void vstr(FPDoubleRegisterID rd, RegisterID rn, int32_t imm)
     {
     {
-        m_formatter.vfpOp(0x0b40ee30 | doubleRegisterMask(rd, 6, 28) | doubleRegisterMask(rn, 23, 0) | doubleRegisterMask(rm, 21, 16));
+        m_formatter.vfpMemOp(OP_VSTR, OP_VSTRb, true, rn, rd, imm);
     }
 
     }
 
+    void vsub_F64(FPDoubleRegisterID rd, FPDoubleRegisterID rn, FPDoubleRegisterID rm)
+    {
+        m_formatter.vfpOp(OP_VSUB_T2, OP_VSUB_T2b, true, rn, rd, rm);
+    }
 
     JmpDst label()
     {
 
     JmpDst label()
     {
@@ -1604,36 +1727,83 @@ public:
     static void repatchLoadPtrToLEA(void* where)
     {
         ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
     static void repatchLoadPtrToLEA(void* where)
     {
         ASSERT(!(reinterpret_cast<intptr_t>(where) & 1));
-
         uint16_t* loadOp = reinterpret_cast<uint16_t*>(where) + 4;
         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));
+        ASSERT((loadOp[0] & 0xfff0) == OP_LDR_reg_T2);
+        ASSERT((loadOp[1] & 0x0ff0) == 0);
+        int rn = loadOp[0] & 0xf;
+        int rt = loadOp[1] >> 12;
+        int rm = loadOp[1] & 0xf;
+
+        loadOp[0] = OP_ADD_reg_T3 | rn;
+        loadOp[1] = rt << 8 | rm;
+        ExecutableAllocator::cacheFlush(loadOp, sizeof(uint32_t));
     }
 
 private:
     }
 
 private:
+    // VFP operations commonly take one or more 5-bit operands, typically representing a
+    // floating point register number.  This will commonly be encoded in the instruction
+    // in two parts, with one single bit field, and one 4-bit field.  In the case of
+    // double precision operands the high bit of the register number will be encoded
+    // separately, and for single precision operands the high bit of the register number
+    // will be encoded individually.
+    // VFPOperand encapsulates a 5-bit VFP operand, with bits 0..3 containing the 4-bit
+    // field to be encoded together in the instruction (the low 4-bits of a double
+    // register number, or the high 4-bits of a single register number), and bit 4
+    // contains the bit value to be encoded individually.
+    struct VFPOperand {
+        explicit VFPOperand(uint32_t value)
+            : m_value(value)
+        {
+            ASSERT(!(m_value & ~0x1f));
+        }
 
 
-    // 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;
+        VFPOperand(FPDoubleRegisterID reg)
+            : m_value(reg)
+        {
         }
 
         }
 
-        // 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;
+        VFPOperand(RegisterID reg)
+            : m_value(reg)
+        {
+        }
 
 
-        m_formatter.vfpOp(0x0b00ed00 | offset | (up << 7) | (isLoad << 4) | doubleRegisterMask(rd, 6, 28) | rn);
+        VFPOperand(FPSingleRegisterID reg)
+            : m_value(((reg & 1) << 4) | (reg >> 1)) // rotate the lowest bit of 'reg' to the top.
+        {
+        }
+
+        uint32_t bits1()
+        {
+            return m_value >> 4;
+        }
+
+        uint32_t bits4()
+        {
+            return m_value & 0xf;
+        }
+
+        uint32_t m_value;
+    };
+
+    VFPOperand vcvtOp(bool toInteger, bool isUnsigned, bool isRoundZero)
+    {
+        // Cannot specify rounding when converting to float.
+        ASSERT(toInteger || !isRoundZero);
+
+        uint32_t op = 0x8;
+        if (toInteger) {
+            // opc2 indicates both toInteger & isUnsigned.
+            op |= isUnsigned ? 0x4 : 0x5;
+            // 'op' field in instruction is isRoundZero
+            if (isRoundZero)
+                op |= 0x10;
+        } else {
+            // 'op' field in instruction is isUnsigned
+            if (!isUnsigned)
+                op |= 0x10;
+        }
+        return VFPOperand(op);
     }
 
     static void setInt32(void* code, uint32_t value)
     }
 
     static void setInt32(void* code, uint32_t value)
@@ -1704,7 +1874,20 @@ private:
             || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)) );
 
         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
             || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)) );
 
         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
-        if (((relative << 7) >> 7) == relative) {
+
+        // From Cortex-A8 errata:
+        // If the 32-bit Thumb-2 branch instruction spans two 4KiB regions and
+        // the target of the branch falls within the first region it is
+        // possible for the processor to incorrectly determine the branch
+        // instruction, and it is also possible in some cases for the processor
+        // to enter a deadlock state.
+        // The instruction is spanning two pages if it ends at an address ending 0x002
+        bool spansTwo4K = ((reinterpret_cast<intptr_t>(instruction) & 0xfff) == 0x002);
+        // The target is in the first page if the jump branch back by [3..0x1002] bytes
+        bool targetInFirstPage = (relative >= -0x1002) && (relative < -2);
+        bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage;
+
+        if (((relative << 7) >> 7) == relative && !wouldTriggerA8Errata) {
             // ARM encoding for the top two bits below the sign bit is 'peculiar'.
             if (relative >= 0)
                 relative ^= 0xC00000;
             // ARM encoding for the top two bits below the sign bit is 'peculiar'.
             if (relative >= 0)
                 relative ^= 0xC00000;
@@ -1810,11 +1993,35 @@ private:
             m_buffer.putShort((reg2 << 12) | imm);
         }
 
             m_buffer.putShort((reg2 << 12) | imm);
         }
 
-        void vfpOp(int32_t op)
+        // Formats up instructions of the pattern:
+        //    111111111B11aaaa:bbbb222SA2C2cccc
+        // Where 1s in the pattern come from op1, 2s in the pattern come from op2, S is the provided size bit.
+        // Operands provide 5 bit values of the form Aaaaa, Bbbbb, Ccccc.
+        void vfpOp(OpcodeID1 op1, OpcodeID2 op2, bool size, VFPOperand a, VFPOperand b, VFPOperand c)
         {
         {
-            m_buffer.putInt(op);
+            ASSERT(!(op1 & 0x004f));
+            ASSERT(!(op2 & 0xf1af));
+            m_buffer.putShort(op1 | b.bits1() << 6 | a.bits4());
+            m_buffer.putShort(op2 | b.bits4() << 12 | size << 8 | a.bits1() << 7 | c.bits1() << 5 | c.bits4());
         }
 
         }
 
+        // 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 vfpMemOp(OpcodeID1 op1, OpcodeID2 op2, bool size, RegisterID rn, VFPOperand rd, int32_t imm)
+        {
+            bool up = true;
+            if (imm < 0) {
+                imm = -imm;
+                up = false;
+            }
+            
+            uint32_t offset = imm;
+            ASSERT(!(offset & ~0x3fc));
+            offset >>= 2;
+
+            m_buffer.putShort(op1 | (up << 7) | rd.bits1() << 6 | rn);
+            m_buffer.putShort(op2 | rd.bits4() << 12 | size << 8 | offset);
+        }
 
         // Administrative methods:
 
 
         // Administrative methods:
 
index 198e8d10adffa84fc078811d7ebf177df68192ad..aab908957ecd03611bc00414db564bed85d17db7 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef AbstractMacroAssembler_h
 #define AbstractMacroAssembler_h
 
 #ifndef AbstractMacroAssembler_h
 #define AbstractMacroAssembler_h
 
-#include <wtf/Platform.h>
-
 #include <MacroAssemblerCodeRef.h>
 #include <CodeLocation.h>
 #include <wtf/Noncopyable.h>
 #include <MacroAssemblerCodeRef.h>
 #include <CodeLocation.h>
 #include <wtf/Noncopyable.h>
@@ -51,7 +49,6 @@ public:
     class Jump;
 
     typedef typename AssemblerType::RegisterID RegisterID;
     class Jump;
 
     typedef typename AssemblerType::RegisterID RegisterID;
-    typedef typename AssemblerType::FPRegisterID FPRegisterID;
     typedef typename AssemblerType::JmpSrc JmpSrc;
     typedef typename AssemblerType::JmpDst JmpDst;
 
     typedef typename AssemblerType::JmpSrc JmpSrc;
     typedef typename AssemblerType::JmpDst JmpDst;
 
@@ -83,6 +80,17 @@ public:
         int32_t offset;
     };
 
         int32_t offset;
     };
 
+    struct ExtendedAddress {
+        explicit ExtendedAddress(RegisterID base, intptr_t offset = 0)
+            : base(base)
+            , offset(offset)
+        {
+        }
+        
+        RegisterID base;
+        intptr_t offset;
+    };
+
     // ImplicitAddress:
     //
     // This class is used for explicit 'load' and 'store' operations
     // ImplicitAddress:
     //
     // This class is used for explicit 'load' and 'store' operations
@@ -151,7 +159,7 @@ public:
     // in a class requiring explicit construction in order to differentiate
     // from pointers used as absolute addresses to memory operations
     struct ImmPtr {
     // 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)
+        explicit ImmPtr(const void* value)
             : m_value(value)
         {
         }
             : m_value(value)
         {
         }
@@ -161,7 +169,7 @@ public:
             return reinterpret_cast<intptr_t>(m_value);
         }
 
             return reinterpret_cast<intptr_t>(m_value);
         }
 
-        void* m_value;
+        const void* m_value;
     };
 
     // Imm32:
     };
 
     // Imm32:
@@ -173,7 +181,7 @@ public:
     struct Imm32 {
         explicit Imm32(int32_t value)
             : m_value(value)
     struct Imm32 {
         explicit Imm32(int32_t value)
             : m_value(value)
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
             , m_isPointer(false)
 #endif
         {
             , m_isPointer(false)
 #endif
         {
@@ -182,7 +190,7 @@ public:
 #if !CPU(X86_64)
         explicit Imm32(ImmPtr ptr)
             : m_value(ptr.asIntptr())
 #if !CPU(X86_64)
         explicit Imm32(ImmPtr ptr)
             : m_value(ptr.asIntptr())
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
             , m_isPointer(true)
 #endif
         {
             , m_isPointer(true)
 #endif
         {
@@ -190,13 +198,14 @@ public:
 #endif
 
         int32_t m_value;
 #endif
 
         int32_t m_value;
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
         // 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.
         // 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.
+        // Same for MIPS.
         bool m_isPointer;
 #endif
     };
         bool m_isPointer;
 #endif
     };
index 073906a526439e7f58fff1e29364d81cca30eb5e..e2fb8a1cc68d019c0ed4305e9e5c0b3611bafd69 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef AssemblerBuffer_h
 #define AssemblerBuffer_h
 
 #ifndef AssemblerBuffer_h
 #define AssemblerBuffer_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER)
 
 #include "stdint.h"
 #if ENABLE(ASSEMBLER)
 
 #include "stdint.h"
index af3c3be07ec00314e39d8c42f0344a9a09583884..b1c537e1e3e0d2748e3175adf810ffd16101dbfe 100644 (file)
@@ -27,8 +27,6 @@
 #ifndef AssemblerBufferWithConstantPool_h
 #define AssemblerBufferWithConstantPool_h
 
 #ifndef AssemblerBufferWithConstantPool_h
 #define AssemblerBufferWithConstantPool_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER)
 
 #include "AssemblerBuffer.h"
 #if ENABLE(ASSEMBLER)
 
 #include "AssemblerBuffer.h"
index b910b6f8826f980bbf11da84254bd4dc29b0dfb2..cab28cd905c1695ca447c6c896c5bf918bf0c99d 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef CodeLocation_h
 #define CodeLocation_h
 
 #ifndef CodeLocation_h
 #define CodeLocation_h
 
-#include <wtf/Platform.h>
 
 #include <MacroAssemblerCodeRef.h>
 
 
 #include <MacroAssemblerCodeRef.h>
 
index 6d0811703cdcc78bb4ad462aacfcb84c16b91263..47cac5ab63cc9ff952898df4c1dfa9b0ad974560 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef LinkBuffer_h
 #define LinkBuffer_h
 
 #ifndef LinkBuffer_h
 #define LinkBuffer_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER)
 
 #include <MacroAssembler.h>
 #if ENABLE(ASSEMBLER)
 
 #include <MacroAssembler.h>
diff --git a/assembler/MIPSAssembler.h b/assembler/MIPSAssembler.h
new file mode 100644 (file)
index 0000000..ea35268
--- /dev/null
@@ -0,0 +1,944 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 University of Szeged
+ * All rights reserved.
+ * Copyright (C) 2010 MIPS Technologies, 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 MIPS TECHNOLOGIES, 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 MIPS TECHNOLOGIES, 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 MIPSAssembler_h
+#define MIPSAssembler_h
+
+#if ENABLE(ASSEMBLER) && CPU(MIPS)
+
+#include "AssemblerBuffer.h"
+#include <wtf/Assertions.h>
+#include <wtf/SegmentedVector.h>
+
+namespace JSC {
+
+typedef uint32_t MIPSWord;
+
+namespace MIPSRegisters {
+typedef enum {
+    r0 = 0,
+    r1,
+    r2,
+    r3,
+    r4,
+    r5,
+    r6,
+    r7,
+    r8,
+    r9,
+    r10,
+    r11,
+    r12,
+    r13,
+    r14,
+    r15,
+    r16,
+    r17,
+    r18,
+    r19,
+    r20,
+    r21,
+    r22,
+    r23,
+    r24,
+    r25,
+    r26,
+    r27,
+    r28,
+    r29,
+    r30,
+    r31,
+    zero = r0,
+    at = r1,
+    v0 = r2,
+    v1 = r3,
+    a0 = r4,
+    a1 = r5,
+    a2 = r6,
+    a3 = r7,
+    t0 = r8,
+    t1 = r9,
+    t2 = r10,
+    t3 = r11,
+    t4 = r12,
+    t5 = r13,
+    t6 = r14,
+    t7 = r15,
+    s0 = r16,
+    s1 = r17,
+    s2 = r18,
+    s3 = r19,
+    s4 = r20,
+    s5 = r21,
+    s6 = r22,
+    s7 = r23,
+    t8 = r24,
+    t9 = r25,
+    k0 = r26,
+    k1 = r27,
+    gp = r28,
+    sp = r29,
+    fp = r30,
+    ra = r31
+} RegisterID;
+
+typedef enum {
+    f0,
+    f1,
+    f2,
+    f3,
+    f4,
+    f5,
+    f6,
+    f7,
+    f8,
+    f9,
+    f10,
+    f11,
+    f12,
+    f13,
+    f14,
+    f15,
+    f16,
+    f17,
+    f18,
+    f19,
+    f20,
+    f21,
+    f22,
+    f23,
+    f24,
+    f25,
+    f26,
+    f27,
+    f28,
+    f29,
+    f30,
+    f31
+} FPRegisterID;
+
+} // namespace MIPSRegisters
+
+class MIPSAssembler {
+public:
+    typedef MIPSRegisters::RegisterID RegisterID;
+    typedef MIPSRegisters::FPRegisterID FPRegisterID;
+    typedef SegmentedVector<int, 64> Jumps;
+
+    MIPSAssembler()
+    {
+    }
+
+    // MIPS instruction opcode field position
+    enum {
+        OP_SH_RD = 11,
+        OP_SH_RT = 16,
+        OP_SH_RS = 21,
+        OP_SH_SHAMT = 6,
+        OP_SH_CODE = 16,
+        OP_SH_FD = 6,
+        OP_SH_FS = 11,
+        OP_SH_FT = 16
+    };
+
+    class JmpSrc {
+        friend class MIPSAssembler;
+    public:
+        JmpSrc()
+            : m_offset(-1)
+        {
+        }
+
+    private:
+        JmpSrc(int offset)
+            : m_offset(offset)
+        {
+        }
+
+        int m_offset;
+    };
+
+    class JmpDst {
+        friend class MIPSAssembler;
+    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;
+    };
+
+    void emitInst(MIPSWord op)
+    {
+        void* oldBase = m_buffer.data();
+
+        m_buffer.putInt(op);
+
+        void* newBase = m_buffer.data();
+        if (oldBase != newBase)
+            relocateJumps(oldBase, newBase);
+    }
+
+    void nop()
+    {
+        emitInst(0x00000000);
+    }
+
+    /* Need to insert one load data delay nop for mips1.  */
+    void loadDelayNop()
+    {
+#if WTF_MIPS_ISA(1)
+        nop();
+#endif
+    }
+
+    /* Need to insert one coprocessor access delay nop for mips1.  */
+    void copDelayNop()
+    {
+#if WTF_MIPS_ISA(1)
+        nop();
+#endif
+    }
+
+    void move(RegisterID rd, RegisterID rs)
+    {
+        /* addu */
+        emitInst(0x00000021 | (rd << OP_SH_RD) | (rs << OP_SH_RS));
+    }
+
+    /* Set an immediate value to a register.  This may generate 1 or 2
+       instructions.  */
+    void li(RegisterID dest, int imm)
+    {
+        if (imm >= -32768 && imm <= 32767)
+            addiu(dest, MIPSRegisters::zero, imm);
+        else if (imm >= 0 && imm < 65536)
+            ori(dest, MIPSRegisters::zero, imm);
+        else {
+            lui(dest, imm >> 16);
+            if (imm & 0xffff)
+                ori(dest, dest, imm);
+        }
+    }
+
+    void lui(RegisterID rt, int imm)
+    {
+        emitInst(0x3c000000 | (rt << OP_SH_RT) | (imm & 0xffff));
+    }
+
+    void addiu(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x24000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void addu(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000021 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void subu(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000023 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void mult(RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000018 | (rs << OP_SH_RS) | (rt << OP_SH_RT));
+    }
+
+    void mfhi(RegisterID rd)
+    {
+        emitInst(0x00000010 | (rd << OP_SH_RD));
+    }
+
+    void mflo(RegisterID rd)
+    {
+        emitInst(0x00000012 | (rd << OP_SH_RD));
+    }
+
+    void mul(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+#if WTF_MIPS_ISA_AT_LEAST(32) 
+        emitInst(0x70000002 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+#else
+        mult(rs, rt);
+        mflo(rd);
+#endif
+    }
+
+    void andInsn(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000024 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void andi(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x30000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void nor(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000027 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void orInsn(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000025 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void ori(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x34000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void xorInsn(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000026 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void xori(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x38000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void slt(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x0000002a | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void sltu(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x0000002b | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void sltiu(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x2c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void sll(RegisterID rd, RegisterID rt, int shamt)
+    {
+        emitInst(0x00000000 | (rd << OP_SH_RD) | (rt << OP_SH_RT)
+                 | ((shamt & 0x1f) << OP_SH_SHAMT));
+    }
+
+    void sllv(RegisterID rd, RegisterID rt, int rs)
+    {
+        emitInst(0x00000004 | (rd << OP_SH_RD) | (rt << OP_SH_RT)
+                 | (rs << OP_SH_RS));
+    }
+
+    void sra(RegisterID rd, RegisterID rt, int shamt)
+    {
+        emitInst(0x00000003 | (rd << OP_SH_RD) | (rt << OP_SH_RT)
+                 | ((shamt & 0x1f) << OP_SH_SHAMT));
+    }
+
+    void srav(RegisterID rd, RegisterID rt, RegisterID rs)
+    {
+        emitInst(0x00000007 | (rd << OP_SH_RD) | (rt << OP_SH_RT)
+                 | (rs << OP_SH_RS));
+    }
+
+    void lbu(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x90000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void lw(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x8c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void lwl(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x88000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void lwr(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x98000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void lhu(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x94000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void sw(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0xac000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+    }
+
+    void jr(RegisterID rs)
+    {
+        emitInst(0x00000008 | (rs << OP_SH_RS));
+    }
+
+    void jalr(RegisterID rs)
+    {
+        emitInst(0x0000f809 | (rs << OP_SH_RS));
+    }
+
+    void jal()
+    {
+        emitInst(0x0c000000);
+    }
+
+    void bkpt()
+    {
+        int value = 512; /* BRK_BUG */
+        emitInst(0x0000000d | ((value & 0x3ff) << OP_SH_CODE));
+    }
+
+    void bgez(RegisterID rs, int imm)
+    {
+        emitInst(0x04010000 | (rs << OP_SH_RS) | (imm & 0xffff));
+    }
+
+    void bltz(RegisterID rs, int imm)
+    {
+        emitInst(0x04000000 | (rs << OP_SH_RS) | (imm & 0xffff));
+    }
+
+    void beq(RegisterID rs, RegisterID rt, int imm)
+    {
+        emitInst(0x10000000 | (rs << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff));
+    }
+
+    void bne(RegisterID rs, RegisterID rt, int imm)
+    {
+        emitInst(0x14000000 | (rs << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff));
+    }
+
+    void bc1t()
+    {
+        emitInst(0x45010000);
+    }
+
+    void bc1f()
+    {
+        emitInst(0x45000000);
+    }
+
+    JmpSrc newJmpSrc()
+    {
+        return JmpSrc(m_buffer.size());
+    }
+
+    void appendJump()
+    {
+        m_jumps.append(m_buffer.size());
+    }
+
+    void addd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200000 | (fd << OP_SH_FD) | (fs << OP_SH_FS)
+                 | (ft << OP_SH_FT));
+    }
+
+    void subd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200001 | (fd << OP_SH_FD) | (fs << OP_SH_FS)
+                 | (ft << OP_SH_FT));
+    }
+
+    void muld(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200002 | (fd << OP_SH_FD) | (fs << OP_SH_FS)
+                 | (ft << OP_SH_FT));
+    }
+
+    void lwc1(FPRegisterID ft, RegisterID rs, int offset)
+    {
+        emitInst(0xc4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        copDelayNop();
+    }
+
+    void ldc1(FPRegisterID ft, RegisterID rs, int offset)
+    {
+        emitInst(0xd4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+    }
+
+    void swc1(FPRegisterID ft, RegisterID rs, int offset)
+    {
+        emitInst(0xe4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+    }
+
+    void sdc1(FPRegisterID ft, RegisterID rs, int offset)
+    {
+        emitInst(0xf4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+    }
+
+    void mtc1(RegisterID rt, FPRegisterID fs)
+    {
+        emitInst(0x44800000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
+        copDelayNop();
+    }
+
+    void mfc1(RegisterID rt, FPRegisterID fs)
+    {
+        emitInst(0x44000000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
+        copDelayNop();
+    }
+
+    void truncwd(FPRegisterID fd, FPRegisterID fs)
+    {
+        emitInst(0x4620000d | (fd << OP_SH_FD) | (fs << OP_SH_FS));
+    }
+
+    void cvtdw(FPRegisterID fd, FPRegisterID fs)
+    {
+        emitInst(0x46800021 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
+    }
+
+    void ceqd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200032 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cngtd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x4620003f | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cnged(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x4620003d | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cltd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x4620003c | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cled(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x4620003e | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cueqd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200033 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void coled(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200036 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void coltd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200034 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void culed(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200037 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cultd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200035 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    // General helpers
+
+    JmpDst label()
+    {
+        return JmpDst(m_buffer.size());
+    }
+
+    JmpDst align(int alignment)
+    {
+        while (!m_buffer.isAligned(alignment))
+            bkpt();
+
+        return label();
+    }
+
+    static void* getRelocatedAddress(void* code, JmpSrc jump)
+    {
+        ASSERT(jump.m_offset != -1);
+        void* b = reinterpret_cast<void*>((reinterpret_cast<intptr_t>(code)) + jump.m_offset);
+        return b;
+    }
+
+    static void* getRelocatedAddress(void* code, JmpDst label)
+    {
+        void* b = reinterpret_cast<void*>((reinterpret_cast<intptr_t>(code)) + label.m_offset);
+        return b;
+    }
+
+    static int getDifferenceBetweenLabels(JmpDst from, JmpDst to)
+    {
+        return to.m_offset - from.m_offset;
+    }
+
+    static int getDifferenceBetweenLabels(JmpDst from, JmpSrc to)
+    {
+        return to.m_offset - from.m_offset;
+    }
+
+    static int getDifferenceBetweenLabels(JmpSrc from, JmpDst to)
+    {
+        return to.m_offset - from.m_offset;
+    }
+
+    // Assembler admin methods:
+
+    size_t size() const
+    {
+        return m_buffer.size();
+    }
+
+    void* executableCopy(ExecutablePool* allocator)
+    {
+        void *result = m_buffer.executableCopy(allocator);
+        if (!result)
+            return 0;
+
+        relocateJumps(m_buffer.data(), result);
+        return result;
+    }
+
+    static unsigned getCallReturnOffset(JmpSrc call)
+    {
+        // The return address is after a call and a delay slot instruction
+        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);
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(m_buffer.data()) + from.m_offset);
+        MIPSWord* toPos = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(m_buffer.data()) + to.m_offset);
+
+        ASSERT(!(*(insn - 1)) && !(*(insn - 2)) && !(*(insn - 3)) && !(*(insn - 5)));
+        insn = insn - 6;
+        linkWithOffset(insn, toPos);
+    }
+
+    static void linkJump(void* code, JmpSrc from, void* to)
+    {
+        ASSERT(from.m_offset != -1);
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
+
+        ASSERT(!(*(insn - 1)) && !(*(insn - 2)) && !(*(insn - 3)) && !(*(insn - 5)));
+        insn = insn - 6;
+        linkWithOffset(insn, to);
+    }
+
+    static void linkCall(void* code, JmpSrc from, void* to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
+        linkCallInternal(insn, to);
+    }
+
+    static void linkPointer(void* code, JmpDst from, void* to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
+        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
+        *insn = (*insn & 0xffff0000) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
+        insn++;
+        ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
+        *insn = (*insn & 0xffff0000) | (reinterpret_cast<intptr_t>(to) & 0xffff);
+    }
+
+    static void relinkJump(void* from, void* to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+
+        ASSERT(!(*(insn - 1)) && !(*(insn - 5)));
+        insn = insn - 6;
+        int flushSize = linkWithOffset(insn, to);
+
+        ExecutableAllocator::cacheFlush(insn, flushSize);
+    }
+
+    static void relinkCall(void* from, void* to)
+    {
+        void* start;
+        int size = linkCallInternal(from, to);
+        if (size == sizeof(MIPSWord))
+            start = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(from) - 2 * sizeof(MIPSWord));
+        else
+            start = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(from) - 4 * sizeof(MIPSWord));
+
+        ExecutableAllocator::cacheFlush(start, size);
+    }
+
+    static void repatchInt32(void* from, int32_t to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
+        *insn = (*insn & 0xffff0000) | ((to >> 16) & 0xffff);
+        insn++;
+        ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
+        *insn = (*insn & 0xffff0000) | (to & 0xffff);
+        insn--;
+        ExecutableAllocator::cacheFlush(insn, 2 * sizeof(MIPSWord));
+    }
+
+    static void repatchPointer(void* from, void* to)
+    {
+        repatchInt32(from, reinterpret_cast<int32_t>(to));
+    }
+
+    static void repatchLoadPtrToLEA(void* from)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+        insn = insn + 3;
+        ASSERT((*insn & 0xfc000000) == 0x8c000000); // lw
+        /* lw -> addiu */
+        *insn = 0x24000000 | (*insn & 0x03ffffff);
+
+        ExecutableAllocator::cacheFlush(insn, sizeof(MIPSWord));
+    }
+
+private:
+
+    /* Update each jump in the buffer of newBase.  */
+    void relocateJumps(void* oldBase, void* newBase)
+    {
+        // Check each jump
+        for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) {
+            int pos = *iter;
+            MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(newBase) + pos);
+            insn = insn + 2;
+            // Need to make sure we have 5 valid instructions after pos
+            if ((unsigned int)pos >= m_buffer.size() - 5 * sizeof(MIPSWord))
+                continue;
+
+            if ((*insn & 0xfc000000) == 0x08000000) { // j
+                int offset = *insn & 0x03ffffff;
+                int oldInsnAddress = (int)insn - (int)newBase + (int)oldBase;
+                int topFourBits = (oldInsnAddress + 4) >> 28;
+                int oldTargetAddress = (topFourBits << 28) | (offset << 2);
+                int newTargetAddress = oldTargetAddress - (int)oldBase + (int)newBase;
+                int newInsnAddress = (int)insn;
+                if (((newInsnAddress + 4) >> 28) == (newTargetAddress >> 28))
+                    *insn = 0x08000000 | ((newTargetAddress >> 2) & 0x3ffffff);
+                else {
+                    /* lui */
+                    *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
+                    /* ori */
+                    *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
+                    /* jr */
+                    *(insn + 2) = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
+                }
+            } else if ((*insn & 0xffe00000) == 0x3c000000) { // lui
+                int high = (*insn & 0xffff) << 16;
+                int low = *(insn + 1) & 0xffff;
+                int oldTargetAddress = high | low;
+                int newTargetAddress = oldTargetAddress - (int)oldBase + (int)newBase;
+                /* lui */
+                *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
+                /* ori */
+                *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
+            }
+        }
+    }
+
+    static int linkWithOffset(MIPSWord* insn, void* to)
+    {
+        ASSERT((*insn & 0xfc000000) == 0x10000000 // beq
+               || (*insn & 0xfc000000) == 0x14000000 // bne
+               || (*insn & 0xffff0000) == 0x45010000 // bc1t
+               || (*insn & 0xffff0000) == 0x45000000); // bc1f
+        intptr_t diff = (reinterpret_cast<intptr_t>(to)
+                         - reinterpret_cast<intptr_t>(insn) - 4) >> 2;
+
+        if (diff < -32768 || diff > 32767 || *(insn + 2) != 0x10000003) {
+            /*
+                Convert the sequence:
+                  beq $2, $3, target
+                  nop
+                  b 1f
+                  nop
+                  nop
+                  nop
+                1:
+
+                to the new sequence if possible:
+                  bne $2, $3, 1f
+                  nop
+                  j    target
+                  nop
+                  nop
+                  nop
+                1:
+
+                OR to the new sequence:
+                  bne $2, $3, 1f
+                  nop
+                  lui $25, target >> 16
+                  ori $25, $25, target & 0xffff
+                  jr $25
+                  nop
+                1:
+
+                Note: beq/bne/bc1t/bc1f are converted to bne/beq/bc1f/bc1t.
+            */
+
+            if (*(insn + 2) == 0x10000003) {
+                if ((*insn & 0xfc000000) == 0x10000000) // beq
+                    *insn = (*insn & 0x03ff0000) | 0x14000005; // bne
+                else if ((*insn & 0xfc000000) == 0x14000000) // bne
+                    *insn = (*insn & 0x03ff0000) | 0x10000005; // beq
+                else if ((*insn & 0xffff0000) == 0x45010000) // bc1t
+                    *insn = 0x45000005; // bc1f
+                else if ((*insn & 0xffff0000) == 0x45000000) // bc1f
+                    *insn = 0x45010005; // bc1t
+                else
+                    ASSERT(0);
+            }
+
+            insn = insn + 2;
+            if ((reinterpret_cast<intptr_t>(insn) + 4) >> 28
+                == reinterpret_cast<intptr_t>(to) >> 28) {
+                *insn = 0x08000000 | ((reinterpret_cast<intptr_t>(to) >> 2) & 0x3ffffff);
+                *(insn + 1) = 0;
+                return 4 * sizeof(MIPSWord);
+            }
+
+            intptr_t newTargetAddress = reinterpret_cast<intptr_t>(to);
+            /* lui */
+            *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
+            /* ori */
+            *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
+            /* jr */
+            *(insn + 2) = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
+            return 5 * sizeof(MIPSWord);
+        }
+
+        *insn = (*insn & 0xffff0000) | (diff & 0xffff);
+        return sizeof(MIPSWord);
+    }
+
+    static int linkCallInternal(void* from, void* to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+        insn = insn - 4;
+
+        if ((*(insn + 2) & 0xfc000000) == 0x0c000000) { // jal
+            if ((reinterpret_cast<intptr_t>(from) - 4) >> 28
+                == reinterpret_cast<intptr_t>(to) >> 28) {
+                *(insn + 2) = 0x0c000000 | ((reinterpret_cast<intptr_t>(to) >> 2) & 0x3ffffff);
+                return sizeof(MIPSWord);
+            }
+
+            /* lui $25, (to >> 16) & 0xffff */
+            *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
+            /* ori $25, $25, to & 0xffff */
+            *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (reinterpret_cast<intptr_t>(to) & 0xffff);
+            /* jalr $25 */
+            *(insn + 2) = 0x0000f809 | (MIPSRegisters::t9 << OP_SH_RS);
+            return 3 * sizeof(MIPSWord);
+        }
+
+        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
+        ASSERT((*(insn + 1) & 0xfc000000) == 0x34000000); // ori
+
+        /* lui */
+        *insn = (*insn & 0xffff0000) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
+        /* ori */
+        *(insn + 1) = (*(insn + 1) & 0xffff0000) | (reinterpret_cast<intptr_t>(to) & 0xffff);
+        return 2 * sizeof(MIPSWord);
+    }
+
+    AssemblerBuffer m_buffer;
+    Jumps m_jumps;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER) && CPU(MIPS)
+
+#endif // MIPSAssembler_h
index 76bd2057014588dd11678a49638f3f2928d23912..ce1be78a8c7698f3206b089ebde56ae5bc73029e 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef MacroAssembler_h
 #define MacroAssembler_h
 
 #ifndef MacroAssembler_h
 #define MacroAssembler_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER)
 
 #if CPU(ARM_THUMB2)
 #if ENABLE(ASSEMBLER)
 
 #if CPU(ARM_THUMB2)
@@ -38,6 +36,12 @@ namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; };
 #include "MacroAssemblerARM.h"
 namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; };
 
 #include "MacroAssemblerARM.h"
 namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; };
 
+#elif CPU(MIPS)
+#include "MacroAssemblerMIPS.h"
+namespace JSC {
+typedef MacroAssemblerMIPS MacroAssemblerBase;
+};
+
 #elif CPU(X86)
 #include "MacroAssemblerX86.h"
 namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; };
 #elif CPU(X86)
 #include "MacroAssemblerX86.h"
 namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; };
@@ -327,6 +331,11 @@ public:
     {
         return branchSub32(cond, imm, dest);
     }
     {
         return branchSub32(cond, imm, dest);
     }
+    using MacroAssemblerBase::branchTest8;
+    Jump branchTest8(Condition cond, ExtendedAddress address, Imm32 mask = Imm32(-1))
+    {
+        return MacroAssemblerBase::branchTest8(cond, Address(address.base, address.offset), mask);
+    }
 #endif
 
 };
 #endif
 
 };
index 21b8de8fffdde06583d34c31acd03f2f0d48178e..2a053d4896cf06df6126e56b3853a0f2320312d7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2008 Apple Inc.
 /*
  * Copyright (C) 2008 Apple Inc.
- * Copyright (C) 2009 University of Szeged
+ * Copyright (C) 2009, 2010 University of Szeged
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,8 +28,6 @@
 #ifndef MacroAssemblerARM_h
 #define MacroAssemblerARM_h
 
 #ifndef MacroAssemblerARM_h
 #define MacroAssemblerARM_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
 
 #include "ARMAssembler.h"
 #if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
 
 #include "ARMAssembler.h"
@@ -42,6 +40,8 @@ class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> {
     static const int DoubleConditionBitSpecial = 0x10;
     COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes);
 public:
     static const int DoubleConditionBitSpecial = 0x10;
     COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes);
 public:
+    typedef ARMRegisters::FPRegisterID FPRegisterID;
+
     enum Condition {
         Equal = ARMAssembler::EQ,
         NotEqual = ARMAssembler::NE,
     enum Condition {
         Equal = ARMAssembler::EQ,
         NotEqual = ARMAssembler::NE,
@@ -180,6 +180,20 @@ public:
     {
         m_assembler.movs_r(dest, m_assembler.asr(dest, imm.m_value & 0x1f));
     }
     {
         m_assembler.movs_r(dest, m_assembler.asr(dest, imm.m_value & 0x1f));
     }
+    
+    void urshift32(RegisterID shift_amount, RegisterID dest)
+    {
+        ARMWord w = ARMAssembler::getOp2(0x1f);
+        ASSERT(w != ARMAssembler::INVALID_IMM);
+        m_assembler.and_r(ARMRegisters::S0, shift_amount, w);
+        
+        m_assembler.movs_r(dest, m_assembler.lsr_r(dest, ARMRegisters::S0));
+    }
+    
+    void urshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.movs_r(dest, m_assembler.lsr(dest, imm.m_value & 0x1f));
+    }
 
     void sub32(RegisterID src, RegisterID dest)
     {
 
     void sub32(RegisterID src, RegisterID dest)
     {
@@ -214,6 +228,11 @@ public:
         m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
     }
 
         m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
     }
 
+    void load8(ImplicitAddress address, RegisterID dest)
+    {
+        m_assembler.dataTransfer32(true, dest, address.base, address.offset, true);
+    }
+
     void load32(ImplicitAddress address, RegisterID dest)
     {
         m_assembler.dataTransfer32(true, dest, address.base, address.offset);
     void load32(ImplicitAddress address, RegisterID dest)
     {
         m_assembler.dataTransfer32(true, dest, address.base, address.offset);
@@ -256,6 +275,14 @@ public:
         else
             m_assembler.ldrh_d(dest, ARMRegisters::S0, ARMAssembler::getOp2Byte(-address.offset));
     }
         else
             m_assembler.ldrh_d(dest, ARMRegisters::S0, ARMAssembler::getOp2Byte(-address.offset));
     }
+    
+    void load16(ImplicitAddress address, RegisterID dest)
+    {
+        if (address.offset >= 0)
+            m_assembler.ldrh_u(dest, address.base, ARMAssembler::getOp2Byte(address.offset));
+        else
+            m_assembler.ldrh_d(dest, address.base, ARMAssembler::getOp2Byte(-address.offset));   
+    }
 
     DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
     {
 
     DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
     {
@@ -359,6 +386,12 @@ public:
             move(src, dest);
     }
 
             move(src, dest);
     }
 
+    Jump branch8(Condition cond, Address left, Imm32 right)
+    {
+        load8(left, ARMRegisters::S1);
+        return branch32(cond, ARMRegisters::S1, right);
+    }
+
     Jump branch32(Condition cond, RegisterID left, RegisterID right, int useConstantPool = 0)
     {
         m_assembler.cmp_r(left, right);
     Jump branch32(Condition cond, RegisterID left, RegisterID right, int useConstantPool = 0)
     {
         m_assembler.cmp_r(left, right);
@@ -422,6 +455,12 @@ public:
         return m_assembler.jmp(ARMCondition(cond));
     }
 
         return m_assembler.jmp(ARMCondition(cond));
     }
 
+    Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        load8(address, ARMRegisters::S1);
+        return branchTest32(cond, ARMRegisters::S1, mask);
+    }
+
     Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
     {
         ASSERT((cond == Zero) || (cond == NonZero));
     Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
     {
         ASSERT((cond == Zero) || (cond == NonZero));
@@ -459,7 +498,7 @@ public:
 
     void jump(RegisterID target)
     {
 
     void jump(RegisterID target)
     {
-        move(target, ARMRegisters::pc);
+        m_assembler.bx(target);
     }
 
     void jump(Address address)
     }
 
     void jump(Address address)
@@ -530,6 +569,13 @@ public:
         return Jump(m_assembler.jmp(ARMCondition(cond)));
     }
 
         return Jump(m_assembler.jmp(ARMCondition(cond)));
     }
 
+    Jump branchNeg32(Condition cond, RegisterID srcDest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        neg32(srcDest);
+        return Jump(m_assembler.jmp(ARMCondition(cond)));
+    }
+
     Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
     {
         ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
     Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
     {
         ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -544,14 +590,19 @@ public:
 
     Call nearCall()
     {
 
     Call nearCall()
     {
+#if WTF_ARM_ARCH_AT_LEAST(5)
+        ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
+        m_assembler.loadBranchTarget(ARMRegisters::S1, ARMAssembler::AL, true);
+        return Call(m_assembler.blx(ARMRegisters::S1), Call::LinkableNear);
+#else
         prepareCall();
         return Call(m_assembler.jmp(ARMAssembler::AL, true), Call::LinkableNear);
         prepareCall();
         return Call(m_assembler.jmp(ARMAssembler::AL, true), Call::LinkableNear);
+#endif
     }
 
     Call call(RegisterID target)
     {
     }
 
     Call call(RegisterID target)
     {
-        prepareCall();
-        move(ARMRegisters::pc, target);
+        m_assembler.blx(target);
         JmpSrc jmpSrc;
         return Call(jmpSrc, Call::None);
     }
         JmpSrc jmpSrc;
         return Call(jmpSrc, Call::None);
     }
@@ -563,7 +614,7 @@ public:
 
     void ret()
     {
 
     void ret()
     {
-        m_assembler.mov_r(ARMRegisters::pc, linkRegister);
+        m_assembler.bx(linkRegister);
     }
 
     void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
     }
 
     void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
@@ -659,8 +710,14 @@ public:
 
     Call call()
     {
 
     Call call()
     {
+#if WTF_ARM_ARCH_AT_LEAST(5)
+        ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
+        m_assembler.loadBranchTarget(ARMRegisters::S1, ARMAssembler::AL, true);
+        return Call(m_assembler.blx(ARMRegisters::S1), Call::Linkable);
+#else
         prepareCall();
         return Call(m_assembler.jmp(ARMAssembler::AL, true), Call::Linkable);
         prepareCall();
         return Call(m_assembler.jmp(ARMAssembler::AL, true), Call::Linkable);
+#endif
     }
 
     Call tailRecursiveCall()
     }
 
     Call tailRecursiveCall()
@@ -718,12 +775,17 @@ public:
         return false;
     }
 
         return false;
     }
 
+    bool supportsFloatingPointSqrt() const
+    {
+        return s_isVFPPresent;
+    }
+
     void loadDouble(ImplicitAddress address, FPRegisterID dest)
     {
         m_assembler.doubleTransfer(true, dest, address.base, address.offset);
     }
 
     void loadDouble(ImplicitAddress address, FPRegisterID dest)
     {
         m_assembler.doubleTransfer(true, dest, address.base, address.offset);
     }
 
-    void loadDouble(void* address, FPRegisterID dest)
+    void loadDouble(const void* address, FPRegisterID dest)
     {
         m_assembler.ldr_un_imm(ARMRegisters::S0, (ARMWord)address);
         m_assembler.fdtr_u(true, dest, ARMRegisters::S0, 0);
     {
         m_assembler.ldr_un_imm(ARMRegisters::S0, (ARMWord)address);
         m_assembler.fdtr_u(true, dest, ARMRegisters::S0, 0);
@@ -779,6 +841,11 @@ public:
         mulDouble(ARMRegisters::SD0, dest);
     }
 
         mulDouble(ARMRegisters::SD0, dest);
     }
 
+    void sqrtDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.fsqrtd_r(dest, src);
+    }
+
     void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
     {
         m_assembler.fmsr_r(dest, src);
     void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
     {
         m_assembler.fmsr_r(dest, src);
@@ -864,44 +931,56 @@ protected:
 
     void prepareCall()
     {
 
     void prepareCall()
     {
+#if WTF_ARM_ARCH_VERSION < 5
         ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
 
         m_assembler.mov_r(linkRegister, ARMRegisters::pc);
         ensureSpace(2 * sizeof(ARMWord), sizeof(ARMWord));
 
         m_assembler.mov_r(linkRegister, ARMRegisters::pc);
+#endif
     }
 
     void call32(RegisterID base, int32_t offset)
     {
     }
 
     void call32(RegisterID base, int32_t offset)
     {
+#if WTF_ARM_ARCH_AT_LEAST(5)
+        int targetReg = ARMRegisters::S1;
+#else
+        int targetReg = ARMRegisters::pc;
+#endif
+        int tmpReg = ARMRegisters::S1;
+
         if (base == ARMRegisters::sp)
             offset += 4;
 
         if (offset >= 0) {
             if (offset <= 0xfff) {
                 prepareCall();
         if (base == ARMRegisters::sp)
             offset += 4;
 
         if (offset >= 0) {
             if (offset <= 0xfff) {
                 prepareCall();
-                m_assembler.dtr_u(true, ARMRegisters::pc, base, offset);
+                m_assembler.dtr_u(true, targetReg, base, offset);
             } else if (offset <= 0xfffff) {
             } else if (offset <= 0xfffff) {
-                m_assembler.add_r(ARMRegisters::S0, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8));
+                m_assembler.add_r(tmpReg, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8));
                 prepareCall();
                 prepareCall();
-                m_assembler.dtr_u(true, ARMRegisters::pc, ARMRegisters::S0, offset & 0xfff);
+                m_assembler.dtr_u(true, targetReg, tmpReg, offset & 0xfff);
             } else {
             } else {
-                ARMWord reg = m_assembler.getImm(offset, ARMRegisters::S0);
+                ARMWord reg = m_assembler.getImm(offset, tmpReg);
                 prepareCall();
                 prepareCall();
-                m_assembler.dtr_ur(true, ARMRegisters::pc, base, reg);
+                m_assembler.dtr_ur(true, targetReg, base, reg);
             }
         } else  {
             offset = -offset;
             if (offset <= 0xfff) {
                 prepareCall();
             }
         } else  {
             offset = -offset;
             if (offset <= 0xfff) {
                 prepareCall();
-                m_assembler.dtr_d(true, ARMRegisters::pc, base, offset);
+                m_assembler.dtr_d(true, targetReg, base, offset);
             } else if (offset <= 0xfffff) {
             } else if (offset <= 0xfffff) {
-                m_assembler.sub_r(ARMRegisters::S0, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8));
+                m_assembler.sub_r(tmpReg, base, ARMAssembler::OP2_IMM | (offset >> 12) | (10 << 8));
                 prepareCall();
                 prepareCall();
-                m_assembler.dtr_d(true, ARMRegisters::pc, ARMRegisters::S0, offset & 0xfff);
+                m_assembler.dtr_d(true, targetReg, tmpReg, offset & 0xfff);
             } else {
             } else {
-                ARMWord reg = m_assembler.getImm(offset, ARMRegisters::S0);
+                ARMWord reg = m_assembler.getImm(offset, tmpReg);
                 prepareCall();
                 prepareCall();
-                m_assembler.dtr_dr(true, ARMRegisters::pc, base, reg);
+                m_assembler.dtr_dr(true, targetReg, base, reg);
             }
         }
             }
         }
+#if WTF_ARM_ARCH_AT_LEAST(5)
+        m_assembler.blx(targetReg);
+#endif
     }
 
 private:
     }
 
 private:
index 5d6513bb6f5b124fa562445de7dc9db26cf5a813..b9cc8561228b7864c77c2459c559f30e18b04f1d 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009 Apple Inc. All rights reserved.
 /*
  * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 University of Szeged
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +27,6 @@
 #ifndef MacroAssemblerARMv7_h
 #define MacroAssemblerARMv7_h
 
 #ifndef MacroAssemblerARMv7_h
 #define MacroAssemblerARMv7_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER)
 
 #include "ARMv7Assembler.h"
 #if ENABLE(ASSEMBLER)
 
 #include "ARMv7Assembler.h"
@@ -39,10 +38,13 @@ 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.
     // 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 ARMRegisters::RegisterID dataTempRegister = ARMRegisters::ip;
+    static const RegisterID dataTempRegister = ARMRegisters::ip;
     static const RegisterID addressTempRegister = ARMRegisters::r3;
     static const RegisterID addressTempRegister = ARMRegisters::r3;
-    static const FPRegisterID fpTempRegister = ARMRegisters::d7;
 
 
+    static const ARMRegisters::FPDoubleRegisterID fpTempRegister = ARMRegisters::d7;
+    inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); }
+
+public:
     struct ArmAddress {
         enum AddressType {
             HasOffset,
     struct ArmAddress {
         enum AddressType {
             HasOffset,
@@ -74,6 +76,7 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
     };
     
 public:
     };
     
 public:
+    typedef ARMRegisters::FPDoubleRegisterID FPRegisterID;
 
     static const Scale ScalePtr = TimesFour;
 
 
     static const Scale ScalePtr = TimesFour;
 
@@ -223,6 +226,11 @@ public:
         m_assembler.smull(dest, dataTempRegister, src, dataTempRegister);
     }
 
         m_assembler.smull(dest, dataTempRegister, src, dataTempRegister);
     }
 
+    void neg32(RegisterID srcDest)
+    {
+        m_assembler.neg(srcDest, srcDest);
+    }
+
     void not32(RegisterID srcDest)
     {
         m_assembler.mvn(srcDest, srcDest);
     void not32(RegisterID srcDest)
     {
         m_assembler.mvn(srcDest, srcDest);
@@ -258,6 +266,21 @@ public:
     {
         m_assembler.asr(dest, dest, imm.m_value & 0x1f);
     }
     {
         m_assembler.asr(dest, dest, imm.m_value & 0x1f);
     }
+    
+    void urshift32(RegisterID shift_amount, RegisterID dest)
+    {
+        // Clamp the shift to the range 0..31
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(0x1f);
+        ASSERT(armImm.isValid());
+        m_assembler.ARM_and(dataTempRegister, shift_amount, armImm);
+        
+        m_assembler.lsr(dest, dest, dataTempRegister);
+    }
+    
+    void urshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.lsr(dest, dest, imm.m_value & 0x1f);
+    }
 
     void sub32(RegisterID src, RegisterID dest)
     {
 
     void sub32(RegisterID src, RegisterID dest)
     {
@@ -368,6 +391,20 @@ private:
         }
     }
 
         }
     }
 
+    void load8(ArmAddress address, RegisterID dest)
+    {
+        if (address.type == ArmAddress::HasIndex)
+            m_assembler.ldrb(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.ldrb(dest, address.base, armImm);
+        } else {
+            ASSERT(address.u.offset >= -255);
+            m_assembler.ldrb(dest, address.base, address.u.offset, true, false);
+        }
+    }
+
     void store32(RegisterID src, ArmAddress address)
     {
         if (address.type == ArmAddress::HasIndex)
     void store32(RegisterID src, ArmAddress address)
     {
         if (address.type == ArmAddress::HasIndex)
@@ -404,6 +441,11 @@ public:
         m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
     }
 
         m_assembler.ldr(dest, addressTempRegister, ARMThumbImmediate::makeUInt16(0));
     }
 
+    void load8(ImplicitAddress address, RegisterID dest)
+    {
+        load8(setupArmAddress(address), dest);
+    }
+
     DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
     {
         DataLabel32 label = moveWithPatch(Imm32(address.offset), dataTempRegister);
     DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
     {
         DataLabel32 label = moveWithPatch(Imm32(address.offset), dataTempRegister);
@@ -423,6 +465,17 @@ public:
     {
         m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale);
     }
     {
         m_assembler.ldrh(dest, makeBaseIndexBase(address), address.index, address.scale);
     }
+    
+    void load16(ImplicitAddress address, RegisterID dest)
+    {
+        ARMThumbImmediate armImm = ARMThumbImmediate::makeUInt12(address.offset);
+        if (armImm.isValid())
+            m_assembler.ldrh(dest, address.base, armImm);
+        else {
+            move(Imm32(address.offset), dataTempRegister);
+            m_assembler.ldrh(dest, address.base, dataTempRegister);
+        }
+    }
 
     DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
     {
 
     DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
     {
@@ -476,6 +529,11 @@ public:
     // In short, FIXME:.
     bool supportsFloatingPointTruncate() const { return false; }
 
     // In short, FIXME:.
     bool supportsFloatingPointTruncate() const { return false; }
 
+    bool supportsFloatingPointSqrt() const
+    {
+        return false;
+    }
+
     void loadDouble(ImplicitAddress address, FPRegisterID dest)
     {
         RegisterID base = address.base;
     void loadDouble(ImplicitAddress address, FPRegisterID dest)
     {
         RegisterID base = address.base;
@@ -491,6 +549,12 @@ public:
         m_assembler.vldr(dest, base, offset);
     }
 
         m_assembler.vldr(dest, base, offset);
     }
 
+    void loadDouble(const void* address, FPRegisterID dest)
+    {
+        move(ImmPtr(address), addressTempRegister);
+        m_assembler.vldr(dest, addressTempRegister, 0);
+    }
+
     void storeDouble(FPRegisterID src, ImplicitAddress address)
     {
         RegisterID base = address.base;
     void storeDouble(FPRegisterID src, ImplicitAddress address)
     {
         RegisterID base = address.base;
@@ -517,6 +581,11 @@ public:
         addDouble(fpTempRegister, dest);
     }
 
         addDouble(fpTempRegister, dest);
     }
 
+    void divDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.vdiv_F64(dest, dest, src);
+    }
+
     void subDouble(FPRegisterID src, FPRegisterID dest)
     {
         m_assembler.vsub_F64(dest, dest, src);
     void subDouble(FPRegisterID src, FPRegisterID dest)
     {
         m_assembler.vsub_F64(dest, dest, src);
@@ -539,16 +608,37 @@ public:
         mulDouble(fpTempRegister, dest);
     }
 
         mulDouble(fpTempRegister, dest);
     }
 
+    void sqrtDouble(FPRegisterID, FPRegisterID)
+    {
+        ASSERT_NOT_REACHED();
+    }
+
     void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
     {
     void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
     {
-        m_assembler.vmov(fpTempRegister, src);
-        m_assembler.vcvt_F64_S32(dest, fpTempRegister);
+        m_assembler.vmov(fpTempRegisterAsSingle(), src);
+        m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle());
+    }
+
+    void convertInt32ToDouble(Address address, FPRegisterID dest)
+    {
+        // Fixme: load directly into the fpr!
+        load32(address, dataTempRegister);
+        m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister);
+        m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle());
+    }
+
+    void convertInt32ToDouble(AbsoluteAddress address, FPRegisterID dest)
+    {
+        // Fixme: load directly into the fpr!
+        load32(address.m_ptr, dataTempRegister);
+        m_assembler.vmov(fpTempRegisterAsSingle(), dataTempRegister);
+        m_assembler.vcvt_F64_S32(dest, fpTempRegisterAsSingle());
     }
 
     Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
     {
         m_assembler.vcmp_F64(left, right);
     }
 
     Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
     {
         m_assembler.vcmp_F64(left, right);
-        m_assembler.vmrs_APSR_nzcv_FPSCR();
+        m_assembler.vmrs();
 
         if (cond == DoubleNotEqual) {
             // ConditionNE jumps if NotEqual *or* unordered - force the unordered cases not to jump.
 
         if (cond == DoubleNotEqual) {
             // ConditionNE jumps if NotEqual *or* unordered - force the unordered cases not to jump.
@@ -575,6 +665,27 @@ public:
         return jump();
     }
 
         return jump();
     }
 
+    // Convert '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, 0).
+    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID)
+    {
+        m_assembler.vcvtr_S32_F64(fpTempRegisterAsSingle(), src);
+        m_assembler.vmov(dest, fpTempRegisterAsSingle());
+
+        // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
+        m_assembler.vcvt_F64_S32(fpTempRegister, fpTempRegisterAsSingle());
+        failureCases.append(branchDouble(DoubleNotEqualOrUnordered, src, fpTempRegister));
+
+        // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
+        failureCases.append(branchTest32(Zero, dest));
+    }
+
+    void zeroDouble(FPRegisterID dest)
+    {
+        m_assembler.vmov_F64_0(dest);
+    }
 
     // Stack manipulation operations:
     //
 
     // Stack manipulation operations:
     //
@@ -793,6 +904,19 @@ public:
         return branch32(cond, addressTempRegister, Imm32(right.m_value << 16));
     }
 
         return branch32(cond, addressTempRegister, Imm32(right.m_value << 16));
     }
 
+    Jump branch8(Condition cond, RegisterID left, Imm32 right)
+    {
+        compare32(left, right);
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branch8(Condition cond, Address left, Imm32 right)
+    {
+        // use addressTempRegister incase the branch8 we call uses dataTempRegister. :-/
+        load8(left, addressTempRegister);
+        return branch8(cond, addressTempRegister, right);
+    }
+
     Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
     {
         ASSERT((cond == Zero) || (cond == NonZero));
     Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
     {
         ASSERT((cond == Zero) || (cond == NonZero));
@@ -823,6 +947,21 @@ public:
         return branchTest32(cond, addressTempRegister, mask);
     }
 
         return branchTest32(cond, addressTempRegister, mask);
     }
 
+    Jump branchTest8(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        test32(reg, mask);
+        return Jump(makeBranch(cond));
+    }
+
+    Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        // use addressTempRegister incase the branchTest8 we call uses dataTempRegister. :-/
+        load8(address, addressTempRegister);
+        return branchTest8(cond, addressTempRegister, mask);
+    }
+
     Jump jump()
     {
         return Jump(makeJump());
     Jump jump()
     {
         return Jump(makeJump());
@@ -888,6 +1027,13 @@ public:
         return branch32(NotEqual, addressTempRegister, dataTempRegister);
     }
 
         return branch32(NotEqual, addressTempRegister, dataTempRegister);
     }
 
+    Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
+        m_assembler.orr_S(dest, dest, src);
+        return Jump(makeBranch(cond));
+    }
+
     Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
     {
         ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
     Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
     {
         ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -952,6 +1098,12 @@ public:
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
     }
 
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
     }
 
+    void set32(Condition cond, Address left, RegisterID right, RegisterID dest)
+    {
+        load32(left, dataTempRegister);
+        set32(cond, dataTempRegister, right, dest);
+    }
+
     void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
     {
         compare32(left, right);
     void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
     {
         compare32(left, right);
@@ -960,6 +1112,21 @@ public:
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
     }
 
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
     }
 
+    void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+    {
+        set32(cond, left, right, dest);
+    }
+
+    void set8(Condition cond, Address left, RegisterID right, RegisterID dest)
+    {
+        set32(cond, left, right, dest);
+    }
+
+    void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+    {
+        set32(cond, left, right, dest);
+    }
+
     // FIXME:
     // The mask should be optional... paerhaps the argument order should be
     // dest-src, operations always have a dest? ... possibly not true, considering
     // FIXME:
     // The mask should be optional... paerhaps the argument order should be
     // dest-src, operations always have a dest? ... possibly not true, considering
@@ -973,6 +1140,14 @@ public:
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
     }
 
         m_assembler.mov(dest, ARMThumbImmediate::makeUInt16(0));
     }
 
+    void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest)
+    {
+        load8(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)
     {
 
     DataLabel32 moveWithPatch(Imm32 imm, RegisterID dst)
     {
index cae8bf68e25f26e591ceb2b7d69a55adca98176a..543b0fa2415032bf14cddd0531b263a2929e9f8d 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef MacroAssemblerCodeRef_h
 #define MacroAssemblerCodeRef_h
 
 #ifndef MacroAssemblerCodeRef_h
 #define MacroAssemblerCodeRef_h
 
-#include <wtf/Platform.h>
-
 #include "ExecutableAllocator.h"
 #include "PassRefPtr.h"
 #include "RefPtr.h"
 #include "ExecutableAllocator.h"
 #include "PassRefPtr.h"
 #include "RefPtr.h"
diff --git a/assembler/MacroAssemblerMIPS.h b/assembler/MacroAssemblerMIPS.h
new file mode 100644 (file)
index 0000000..9853c34
--- /dev/null
@@ -0,0 +1,1711 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 MIPS Technologies, 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 MIPS TECHNOLOGIES, 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 MIPS TECHNOLOGIES, 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 MacroAssemblerMIPS_h
+#define MacroAssemblerMIPS_h
+
+#if ENABLE(ASSEMBLER) && CPU(MIPS)
+
+#include "AbstractMacroAssembler.h"
+#include "MIPSAssembler.h"
+
+namespace JSC {
+
+class MacroAssemblerMIPS : public AbstractMacroAssembler<MIPSAssembler> {
+public:
+
+    MacroAssemblerMIPS()
+        : m_fixedWidth(false)
+    {
+    }
+
+    static const Scale ScalePtr = TimesFour;
+
+    // For storing immediate number
+    static const RegisterID immTempRegister = MIPSRegisters::t0;
+    // For storing data loaded from the memory
+    static const RegisterID dataTempRegister = MIPSRegisters::t1;
+    // For storing address base
+    static const RegisterID addrTempRegister = MIPSRegisters::t2;
+    // For storing compare result
+    static const RegisterID cmpTempRegister = MIPSRegisters::t3;
+
+    // FP temp register
+    static const FPRegisterID fpTempRegister = MIPSRegisters::f16;
+
+    enum Condition {
+        Equal,
+        NotEqual,
+        Above,
+        AboveOrEqual,
+        Below,
+        BelowOrEqual,
+        GreaterThan,
+        GreaterThanOrEqual,
+        LessThan,
+        LessThanOrEqual,
+        Overflow,
+        Signed,
+        Zero,
+        NonZero
+    };
+
+    enum DoubleCondition {
+        DoubleEqual,
+        DoubleNotEqual,
+        DoubleGreaterThan,
+        DoubleGreaterThanOrEqual,
+        DoubleLessThan,
+        DoubleLessThanOrEqual,
+        DoubleEqualOrUnordered,
+        DoubleNotEqualOrUnordered,
+        DoubleGreaterThanOrUnordered,
+        DoubleGreaterThanOrEqualOrUnordered,
+        DoubleLessThanOrUnordered,
+        DoubleLessThanOrEqualOrUnordered
+    };
+
+    static const RegisterID stackPointerRegister = MIPSRegisters::sp;
+    static const RegisterID returnAddressRegister = MIPSRegisters::ra;
+
+    // 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.addu(dest, dest, src);
+    }
+
+    void add32(Imm32 imm, RegisterID dest)
+    {
+        add32(imm, dest, dest);
+    }
+
+    void add32(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        if (!imm.m_isPointer && imm.m_value >= -32768 && imm.m_value <= 32767
+            && !m_fixedWidth) {
+            /*
+              addiu     dest, src, imm
+            */
+            m_assembler.addiu(dest, src, imm.m_value);
+        } else {
+            /*
+              li        immTemp, imm
+              addu      dest, src, immTemp
+            */
+            move(imm, immTempRegister);
+            m_assembler.addu(dest, src, immTempRegister);
+        }
+    }
+
+    void add32(Imm32 imm, Address address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+              lw        dataTemp, offset(base)
+              li        immTemp, imm
+              addu      dataTemp, dataTemp, immTemp
+              sw        dataTemp, offset(base)
+            */
+            m_assembler.lw(dataTempRegister, address.base, address.offset);
+            if (!imm.m_isPointer
+                && imm.m_value >= -32768 && imm.m_value <= 32767
+                && !m_fixedWidth)
+                m_assembler.addiu(dataTempRegister, dataTempRegister,
+                                  imm.m_value);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.addu(dataTempRegister, dataTempRegister,
+                                 immTempRegister);
+            }
+            m_assembler.sw(dataTempRegister, address.base, address.offset);
+        } else {
+            /*
+              lui       addrTemp, (offset + 0x8000) >> 16
+              addu      addrTemp, addrTemp, base
+              lw        dataTemp, (offset & 0xffff)(addrTemp)
+              li        immtemp, imm
+              addu      dataTemp, dataTemp, immTemp
+              sw        dataTemp, (offset & 0xffff)(addrTemp)
+            */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lw(dataTempRegister, addrTempRegister, address.offset);
+
+            if (imm.m_value >= -32768 && imm.m_value <= 32767 && !m_fixedWidth)
+                m_assembler.addiu(dataTempRegister, dataTempRegister,
+                                  imm.m_value);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.addu(dataTempRegister, dataTempRegister,
+                                 immTempRegister);
+            }
+            m_assembler.sw(dataTempRegister, addrTempRegister, address.offset);
+        }
+    }
+
+    void add32(Address src, RegisterID dest)
+    {
+        load32(src, dataTempRegister);
+        add32(dataTempRegister, dest);
+    }
+
+    void add32(RegisterID src, Address dest)
+    {
+        if (dest.offset >= -32768 && dest.offset <= 32767 && !m_fixedWidth) {
+            /*
+              lw        dataTemp, offset(base)
+              addu      dataTemp, dataTemp, src
+              sw        dataTemp, offset(base)
+            */
+            m_assembler.lw(dataTempRegister, dest.base, dest.offset);
+            m_assembler.addu(dataTempRegister, dataTempRegister, src);
+            m_assembler.sw(dataTempRegister, dest.base, dest.offset);
+        } else {
+            /*
+              lui       addrTemp, (offset + 0x8000) >> 16
+              addu      addrTemp, addrTemp, base
+              lw        dataTemp, (offset & 0xffff)(addrTemp)
+              addu      dataTemp, dataTemp, src
+              sw        dataTemp, (offset & 0xffff)(addrTemp)
+            */
+            m_assembler.lui(addrTempRegister, (dest.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, dest.base);
+            m_assembler.lw(dataTempRegister, addrTempRegister, dest.offset);
+            m_assembler.addu(dataTempRegister, dataTempRegister, src);
+            m_assembler.sw(dataTempRegister, addrTempRegister, dest.offset);
+        }
+    }
+
+    void add32(Imm32 imm, AbsoluteAddress address)
+    {
+        /*
+           li   addrTemp, address
+           li   immTemp, imm
+           lw   dataTemp, 0(addrTemp)
+           addu dataTemp, dataTemp, immTemp
+           sw   dataTemp, 0(addrTemp)
+        */
+        move(ImmPtr(address.m_ptr), addrTempRegister);
+        m_assembler.lw(dataTempRegister, addrTempRegister, 0);
+        if (!imm.m_isPointer && imm.m_value >= -32768 && imm.m_value <= 32767
+            && !m_fixedWidth)
+            m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value);
+        else {
+            move(imm, immTempRegister);
+            m_assembler.addu(dataTempRegister, dataTempRegister, immTempRegister);
+        }
+        m_assembler.sw(dataTempRegister, addrTempRegister, 0);
+    }
+
+    void and32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.andInsn(dest, dest, src);
+    }
+
+    void and32(Imm32 imm, RegisterID dest)
+    {
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+            move(MIPSRegisters::zero, dest);
+        else if (!imm.m_isPointer && imm.m_value > 0 && imm.m_value < 65535
+                 && !m_fixedWidth)
+            m_assembler.andi(dest, dest, imm.m_value);
+        else {
+            /*
+              li        immTemp, imm
+              and       dest, dest, immTemp
+            */
+            move(imm, immTempRegister);
+            m_assembler.andInsn(dest, dest, immTempRegister);
+        }
+    }
+
+    void lshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.sll(dest, dest, imm.m_value);
+    }
+
+    void lshift32(RegisterID shiftAmount, RegisterID dest)
+    {
+        m_assembler.sllv(dest, dest, shiftAmount);
+    }
+
+    void mul32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.mul(dest, dest, src);
+    }
+
+    void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+            move(MIPSRegisters::zero, dest);
+        else if (!imm.m_isPointer && imm.m_value == 1 && !m_fixedWidth)
+            move(src, dest);
+        else {
+            /*
+                li      dataTemp, imm
+                mul     dest, src, dataTemp
+            */
+            move(imm, dataTempRegister);
+            m_assembler.mul(dest, src, dataTempRegister);
+        }
+    }
+
+    void not32(RegisterID srcDest)
+    {
+        m_assembler.nor(srcDest, srcDest, MIPSRegisters::zero);
+    }
+
+    void or32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.orInsn(dest, dest, src);
+    }
+
+    void or32(Imm32 imm, RegisterID dest)
+    {
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+            return;
+
+        if (!imm.m_isPointer && imm.m_value > 0 && imm.m_value < 65535
+            && !m_fixedWidth) {
+            m_assembler.ori(dest, dest, imm.m_value);
+            return;
+        }
+
+        /*
+            li      dataTemp, imm
+            or      dest, dest, dataTemp
+        */
+        move(imm, dataTempRegister);
+        m_assembler.orInsn(dest, dest, dataTempRegister);
+    }
+
+    void rshift32(RegisterID shiftAmount, RegisterID dest)
+    {
+        m_assembler.srav(dest, dest, shiftAmount);
+    }
+
+    void rshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.sra(dest, dest, imm.m_value);
+    }
+
+    void sub32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.subu(dest, dest, src);
+    }
+
+    void sub32(Imm32 imm, RegisterID dest)
+    {
+        if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
+            && !m_fixedWidth) {
+            /*
+              addiu     dest, src, imm
+            */
+            m_assembler.addiu(dest, dest, -imm.m_value);
+        } else {
+            /*
+              li        immTemp, imm
+              subu      dest, src, immTemp
+            */
+            move(imm, immTempRegister);
+            m_assembler.subu(dest, dest, immTempRegister);
+        }
+    }
+
+    void sub32(Imm32 imm, Address address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+              lw        dataTemp, offset(base)
+              li        immTemp, imm
+              subu      dataTemp, dataTemp, immTemp
+              sw        dataTemp, offset(base)
+            */
+            m_assembler.lw(dataTempRegister, address.base, address.offset);
+            if (!imm.m_isPointer
+                && imm.m_value >= -32767 && imm.m_value <= 32768
+                && !m_fixedWidth)
+                m_assembler.addiu(dataTempRegister, dataTempRegister,
+                                  -imm.m_value);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.subu(dataTempRegister, dataTempRegister,
+                                 immTempRegister);
+            }
+            m_assembler.sw(dataTempRegister, address.base, address.offset);
+        } else {
+            /*
+              lui       addrTemp, (offset + 0x8000) >> 16
+              addu      addrTemp, addrTemp, base
+              lw        dataTemp, (offset & 0xffff)(addrTemp)
+              li        immtemp, imm
+              subu      dataTemp, dataTemp, immTemp
+              sw        dataTemp, (offset & 0xffff)(addrTemp)
+            */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lw(dataTempRegister, addrTempRegister, address.offset);
+
+            if (!imm.m_isPointer
+                && imm.m_value >= -32767 && imm.m_value <= 32768
+                && !m_fixedWidth)
+                m_assembler.addiu(dataTempRegister, dataTempRegister,
+                                  -imm.m_value);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.subu(dataTempRegister, dataTempRegister,
+                                 immTempRegister);
+            }
+            m_assembler.sw(dataTempRegister, addrTempRegister, address.offset);
+        }
+    }
+
+    void sub32(Address src, RegisterID dest)
+    {
+        load32(src, dataTempRegister);
+        sub32(dataTempRegister, dest);
+    }
+
+    void sub32(Imm32 imm, AbsoluteAddress address)
+    {
+        /*
+           li   addrTemp, address
+           li   immTemp, imm
+           lw   dataTemp, 0(addrTemp)
+           subu dataTemp, dataTemp, immTemp
+           sw   dataTemp, 0(addrTemp)
+        */
+        move(ImmPtr(address.m_ptr), addrTempRegister);
+        m_assembler.lw(dataTempRegister, addrTempRegister, 0);
+
+        if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
+            && !m_fixedWidth) {
+            m_assembler.addiu(dataTempRegister, dataTempRegister,
+                              -imm.m_value);
+        } else {
+            move(imm, immTempRegister);
+            m_assembler.subu(dataTempRegister, dataTempRegister, immTempRegister);
+        }
+        m_assembler.sw(dataTempRegister, addrTempRegister, 0);
+    }
+
+    void xor32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.xorInsn(dest, dest, src);
+    }
+
+    void xor32(Imm32 imm, RegisterID dest)
+    {
+        /*
+            li  immTemp, imm
+            xor dest, dest, immTemp
+        */
+        move(imm, immTempRegister);
+        m_assembler.xorInsn(dest, dest, immTempRegister);
+    }
+
+    // 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.
+
+    /* Need to use zero-extened load byte for load8.  */
+    void load8(ImplicitAddress address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth)
+            m_assembler.lbu(dest, address.base, address.offset);
+        else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                lbu     dest, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lbu(dest, addrTempRegister, address.offset);
+        }
+    }
+
+    void load32(ImplicitAddress address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth)
+            m_assembler.lw(dest, address.base, address.offset);
+        else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                lw      dest, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lw(dest, addrTempRegister, address.offset);
+        }
+    }
+
+    void load32(BaseIndex address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lw      dest, address.offset(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lw(dest, addrTempRegister, address.offset);
+        } else {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lui     immTemp, (address.offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, immTemp
+                lw      dest, (address.offset & 0xffff)(at)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister,
+                             immTempRegister);
+            m_assembler.lw(dest, addrTempRegister, address.offset);
+        }
+    }
+
+    void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32764
+            && !m_fixedWidth) {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                (Big-Endian)
+                lwl     dest, address.offset(addrTemp)
+                lwr     dest, address.offset+3(addrTemp)
+                (Little-Endian)
+                lwl     dest, address.offset+3(addrTemp)
+                lwr     dest, address.offset(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+#if CPU(BIG_ENDIAN)
+            m_assembler.lwl(dest, addrTempRegister, address.offset);
+            m_assembler.lwr(dest, addrTempRegister, address.offset + 3);
+#else
+            m_assembler.lwl(dest, addrTempRegister, address.offset + 3);
+            m_assembler.lwr(dest, addrTempRegister, address.offset);
+
+#endif
+        } else {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lui     immTemp, address.offset >> 16
+                ori     immTemp, immTemp, address.offset & 0xffff
+                addu    addrTemp, addrTemp, immTemp
+                (Big-Endian)
+                lw      dest, 0(at)
+                lw      dest, 3(at)
+                (Little-Endian)
+                lw      dest, 3(at)
+                lw      dest, 0(at)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lui(immTempRegister, address.offset >> 16);
+            m_assembler.ori(immTempRegister, immTempRegister, address.offset);
+            m_assembler.addu(addrTempRegister, addrTempRegister,
+                             immTempRegister);
+#if CPU(BIG_ENDIAN)
+            m_assembler.lwl(dest, addrTempRegister, 0);
+            m_assembler.lwr(dest, addrTempRegister, 3);
+#else
+            m_assembler.lwl(dest, addrTempRegister, 3);
+            m_assembler.lwr(dest, addrTempRegister, 0);
+#endif
+        }
+    }
+
+    void load32(void* address, RegisterID dest)
+    {
+        /*
+            li  addrTemp, address
+            lw  dest, 0(addrTemp)
+        */
+        move(ImmPtr(address), addrTempRegister);
+        m_assembler.lw(dest, addrTempRegister, 0);
+    }
+
+    DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
+    {
+        m_fixedWidth = true;
+        /*
+            lui addrTemp, address.offset >> 16
+            ori addrTemp, addrTemp, address.offset & 0xffff
+            addu        addrTemp, addrTemp, address.base
+            lw  dest, 0(addrTemp)
+        */
+        DataLabel32 dataLabel(this);
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.lw(dest, addrTempRegister, 0);
+        m_fixedWidth = false;
+        return dataLabel;
+    }
+
+    Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
+    {
+        m_fixedWidth = true;
+        /*
+            lui         addrTemp, address.offset >> 16
+            ori         addrTemp, addrTemp, address.offset & 0xffff
+            addu        addrTemp, addrTemp, address.base
+            lw          dest, 0(addrTemp)
+        */
+        Label label(this);
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.lw(dest, addrTempRegister, 0);
+        m_fixedWidth = false;
+        return label;
+    }
+
+    Label loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
+    {
+        return loadPtrWithPatchToLEA(address, dest);
+    }
+
+    /* Need to use zero-extened load half-word for load16.  */
+    void load16(BaseIndex address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lhu     dest, address.offset(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lhu(dest, addrTempRegister, address.offset);
+        } else {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lui     immTemp, (address.offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, immTemp
+                lhu     dest, (address.offset & 0xffff)(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister,
+                             immTempRegister);
+            m_assembler.lhu(dest, addrTempRegister, address.offset);
+        }
+    }
+
+    DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
+    {
+        m_fixedWidth = true;
+        /*
+            lui addrTemp, address.offset >> 16
+            ori addrTemp, addrTemp, address.offset & 0xffff
+            addu        addrTemp, addrTemp, address.base
+            sw  src, 0(addrTemp)
+        */
+        DataLabel32 dataLabel(this);
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.sw(src, addrTempRegister, 0);
+        m_fixedWidth = false;
+        return dataLabel;
+    }
+
+    void store32(RegisterID src, ImplicitAddress address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth)
+            m_assembler.sw(src, address.base, address.offset);
+        else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                sw      src, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.sw(src, addrTempRegister, address.offset);
+        }
+    }
+
+    void store32(RegisterID src, BaseIndex address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                sw      src, address.offset(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.sw(src, addrTempRegister, address.offset);
+        } else {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lui     immTemp, (address.offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, immTemp
+                sw      src, (address.offset & 0xffff)(at)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister,
+                             immTempRegister);
+            m_assembler.sw(src, addrTempRegister, address.offset);
+        }
+    }
+
+    void store32(Imm32 imm, ImplicitAddress address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            if (!imm.m_isPointer && !imm.m_value)
+                m_assembler.sw(MIPSRegisters::zero, address.base,
+                               address.offset);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.sw(immTempRegister, address.base, address.offset);
+            }
+        } else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                sw      immTemp, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+                m_assembler.sw(MIPSRegisters::zero, addrTempRegister,
+                               address.offset);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.sw(immTempRegister, addrTempRegister,
+                               address.offset);
+            }
+        }
+    }
+
+    void store32(RegisterID src, void* address)
+    {
+        /*
+            li  addrTemp, address
+            sw  src, 0(addrTemp)
+        */
+        move(ImmPtr(address), addrTempRegister);
+        m_assembler.sw(src, addrTempRegister, 0);
+    }
+
+    void store32(Imm32 imm, void* address)
+    {
+        /*
+            li  immTemp, imm
+            li  addrTemp, address
+            sw  src, 0(addrTemp)
+        */
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth) {
+            move(ImmPtr(address), addrTempRegister);
+            m_assembler.sw(MIPSRegisters::zero, addrTempRegister, 0);
+        } else {
+            move(imm, immTempRegister);
+            move(ImmPtr(address), addrTempRegister);
+            m_assembler.sw(immTempRegister, addrTempRegister, 0);
+        }
+    }
+
+    // Floating-point operations:
+
+    bool supportsFloatingPoint() const
+    {
+#if WTF_MIPS_DOUBLE_FLOAT
+        return true;
+#else
+        return false;
+#endif
+    }
+
+    bool supportsFloatingPointTruncate() const
+    {
+#if WTF_MIPS_DOUBLE_FLOAT && WTF_MIPS_ISA_AT_LEAST(2)
+        return true;
+#else
+        return false;
+#endif
+    }
+
+    // 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.lw(dest, MIPSRegisters::sp, 0);
+        m_assembler.addiu(MIPSRegisters::sp, MIPSRegisters::sp, 4);
+    }
+
+    void push(RegisterID src)
+    {
+        m_assembler.addiu(MIPSRegisters::sp, MIPSRegisters::sp, -4);
+        m_assembler.sw(src, MIPSRegisters::sp, 0);
+    }
+
+    void push(Address address)
+    {
+        load32(address, dataTempRegister);
+        push(dataTempRegister);
+    }
+
+    void push(Imm32 imm)
+    {
+        move(imm, immTempRegister);
+        push(immTempRegister);
+    }
+
+    // Register move operations:
+    //
+    // Move values in registers.
+
+    void move(Imm32 imm, RegisterID dest)
+    {
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+            move(MIPSRegisters::zero, dest);
+        else if (imm.m_isPointer || m_fixedWidth) {
+            m_assembler.lui(dest, imm.m_value >> 16);
+            m_assembler.ori(dest, dest, imm.m_value);
+        } else
+            m_assembler.li(dest, imm.m_value);
+    }
+
+    void move(RegisterID src, RegisterID dest)
+    {
+        if (src != dest || m_fixedWidth)
+            m_assembler.move(dest, src);
+    }
+
+    void move(ImmPtr imm, RegisterID dest)
+    {
+        move(Imm32(imm), dest);
+    }
+
+    void swap(RegisterID reg1, RegisterID reg2)
+    {
+        move(reg1, immTempRegister);
+        move(reg2, reg1);
+        move(immTempRegister, reg2);
+    }
+
+    void signExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        if (src != dest || m_fixedWidth)
+            move(src, dest);
+    }
+
+    void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        if (src != dest || m_fixedWidth)
+            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.
+
+    Jump branch8(Condition cond, Address left, Imm32 right)
+    {
+        // Make sure the immediate value is unsigned 8 bits.
+        ASSERT(!(right.m_value & 0xFFFFFF00));
+        load8(left, dataTempRegister);
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branch32(Condition cond, RegisterID left, RegisterID right)
+    {
+        if (cond == Equal || cond == Zero)
+            return branchEqual(left, right);
+        if (cond == NotEqual || cond == NonZero)
+            return branchNotEqual(left, right);
+        if (cond == Above) {
+            m_assembler.sltu(cmpTempRegister, right, left);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == AboveOrEqual) {
+            m_assembler.sltu(cmpTempRegister, left, right);
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Below) {
+            m_assembler.sltu(cmpTempRegister, left, right);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == BelowOrEqual) {
+            m_assembler.sltu(cmpTempRegister, right, left);
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == GreaterThan) {
+            m_assembler.slt(cmpTempRegister, right, left);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == GreaterThanOrEqual) {
+            m_assembler.slt(cmpTempRegister, left, right);
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == LessThan) {
+            m_assembler.slt(cmpTempRegister, left, right);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == LessThanOrEqual) {
+            m_assembler.slt(cmpTempRegister, right, left);
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Overflow) {
+            /*
+                xor     cmpTemp, left, right
+                bgez    No_overflow, cmpTemp    # same sign bit -> no overflow
+                nop
+                subu    cmpTemp, left, right
+                xor     cmpTemp, cmpTemp, left
+                bgez    No_overflow, cmpTemp    # same sign bit -> no overflow
+                nop
+                b       Overflow
+                nop
+                nop
+                nop
+                nop
+                nop
+              No_overflow:
+            */
+            m_assembler.xorInsn(cmpTempRegister, left, right);
+            m_assembler.bgez(cmpTempRegister, 11);
+            m_assembler.nop();
+            m_assembler.subu(cmpTempRegister, left, right);
+            m_assembler.xorInsn(cmpTempRegister, cmpTempRegister, left);
+            m_assembler.bgez(cmpTempRegister, 7);
+            m_assembler.nop();
+            return jump();
+        }
+        if (cond == Signed) {
+            m_assembler.subu(cmpTempRegister, left, right);
+            // Check if the result is negative.
+            m_assembler.slt(cmpTempRegister, cmpTempRegister,
+                            MIPSRegisters::zero);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        ASSERT(0);
+
+        return Jump();
+    }
+
+    Jump branch32(Condition cond, RegisterID left, Imm32 right)
+    {
+        move(right, immTempRegister);
+        return branch32(cond, left, immTempRegister);
+    }
+
+    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)
+    {
+        load32(left, dataTempRegister);
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branch32(Condition cond, BaseIndex left, Imm32 right)
+    {
+        load32(left, dataTempRegister);
+        // Be careful that the previous load32() uses immTempRegister.
+        // So, we need to put move() after load32().
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right)
+    {
+        load32WithUnalignedHalfWords(left, dataTempRegister);
+        // Be careful that the previous load32WithUnalignedHalfWords()
+        // uses immTempRegister.
+        // So, we need to put move() after load32WithUnalignedHalfWords().
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    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)
+    {
+        load32(left.m_ptr, dataTempRegister);
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branch16(Condition cond, BaseIndex left, RegisterID right)
+    {
+        load16(left, dataTempRegister);
+        return branch32(cond, dataTempRegister, right);
+    }
+
+    Jump branch16(Condition cond, BaseIndex left, Imm32 right)
+    {
+        ASSERT(!(right.m_value & 0xFFFF0000));
+        load16(left, dataTempRegister);
+        // Be careful that the previous load16() uses immTempRegister.
+        // So, we need to put move() after load16().
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        m_assembler.andInsn(cmpTempRegister, reg, mask);
+        if (cond == Zero)
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+    }
+
+    Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        if (mask.m_value == -1 && !m_fixedWidth) {
+            if (cond == Zero)
+                return branchEqual(reg, MIPSRegisters::zero);
+            return branchNotEqual(reg, MIPSRegisters::zero);
+        }
+        move(mask, immTempRegister);
+        return branchTest32(cond, reg, immTempRegister);
+    }
+
+    Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        load32(address, dataTempRegister);
+        return branchTest32(cond, dataTempRegister, mask);
+    }
+
+    Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+    {
+        load32(address, dataTempRegister);
+        return branchTest32(cond, dataTempRegister, mask);
+    }
+
+    Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        load8(address, dataTempRegister);
+        return branchTest32(cond, dataTempRegister, mask);
+    }
+
+    Jump jump()
+    {
+        return branchEqual(MIPSRegisters::zero, MIPSRegisters::zero);
+    }
+
+    void jump(RegisterID target)
+    {
+        m_assembler.jr(target);
+        m_assembler.nop();
+    }
+
+    void jump(Address address)
+    {
+        m_fixedWidth = true;
+        load32(address, MIPSRegisters::t9);
+        m_assembler.jr(MIPSRegisters::t9);
+        m_assembler.nop();
+        m_fixedWidth = false;
+    }
+
+    // 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));
+        if (cond == Overflow) {
+            /*
+                move    dest, dataTemp
+                xor     cmpTemp, dataTemp, src
+                bltz    cmpTemp, No_overflow    # diff sign bit -> no overflow
+                addu    dest, dataTemp, src
+                xor     cmpTemp, dest, dataTemp
+                bgez    cmpTemp, No_overflow    # same sign big -> no overflow
+                nop
+                b       Overflow
+                nop
+                nop
+                nop
+                nop
+                nop
+            No_overflow:
+            */
+            move(dest, dataTempRegister);
+            m_assembler.xorInsn(cmpTempRegister, dataTempRegister, src);
+            m_assembler.bltz(cmpTempRegister, 10);
+            m_assembler.addu(dest, dataTempRegister, src);
+            m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister);
+            m_assembler.bgez(cmpTempRegister, 7);
+            m_assembler.nop();
+            return jump();
+        }
+        if (cond == Signed) {
+            add32(src, dest);
+            // Check if dest is negative.
+            m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Zero) {
+            add32(src, dest);
+            return branchEqual(dest, MIPSRegisters::zero);
+        }
+        if (cond == NonZero) {
+            add32(src, dest);
+            return branchNotEqual(dest, MIPSRegisters::zero);
+        }
+        ASSERT(0);
+        return Jump();
+    }
+
+    Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        move(imm, immTempRegister);
+        return branchAdd32(cond, immTempRegister, dest);
+    }
+
+    Jump branchMul32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        if (cond == Overflow) {
+            /*
+                mult    src, dest
+                mfhi    dataTemp
+                mflo    dest
+                sra     addrTemp, dest, 31
+                beq     dataTemp, addrTemp, No_overflow # all sign bits (bit 63 to bit 31) are the same -> no overflow
+                nop
+                b       Overflow
+                nop
+                nop
+                nop
+                nop
+                nop
+            No_overflow:
+            */
+            m_assembler.mult(src, dest);
+            m_assembler.mfhi(dataTempRegister);
+            m_assembler.mflo(dest);
+            m_assembler.sra(addrTempRegister, dest, 31);
+            m_assembler.beq(dataTempRegister, addrTempRegister, 7);
+            m_assembler.nop();
+            return jump();
+        }
+        if (cond == Signed) {
+            mul32(src, dest);
+            // Check if dest is negative.
+            m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Zero) {
+            mul32(src, dest);
+            return branchEqual(dest, MIPSRegisters::zero);
+        }
+        if (cond == NonZero) {
+            mul32(src, dest);
+            return branchNotEqual(dest, MIPSRegisters::zero);
+        }
+        ASSERT(0);
+        return Jump();
+    }
+
+    Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        move(imm, immTempRegister);
+        move(src, dest);
+        return branchMul32(cond, immTempRegister, dest);
+    }
+
+    Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        if (cond == Overflow) {
+            /*
+                move    dest, dataTemp
+                xor     cmpTemp, dataTemp, src
+                bgez    cmpTemp, No_overflow    # same sign bit -> no overflow
+                subu    dest, dataTemp, src
+                xor     cmpTemp, dest, dataTemp
+                bgez    cmpTemp, No_overflow    # same sign bit -> no overflow
+                nop
+                b       Overflow
+                nop
+                nop
+                nop
+                nop
+                nop
+            No_overflow:
+            */
+            move(dest, dataTempRegister);
+            m_assembler.xorInsn(cmpTempRegister, dataTempRegister, src);
+            m_assembler.bgez(cmpTempRegister, 10);
+            m_assembler.subu(dest, dataTempRegister, src);
+            m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister);
+            m_assembler.bgez(cmpTempRegister, 7);
+            m_assembler.nop();
+            return jump();
+        }
+        if (cond == Signed) {
+            sub32(src, dest);
+            // Check if dest is negative.
+            m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Zero) {
+            sub32(src, dest);
+            return branchEqual(dest, MIPSRegisters::zero);
+        }
+        if (cond == NonZero) {
+            sub32(src, dest);
+            return branchNotEqual(dest, MIPSRegisters::zero);
+        }
+        ASSERT(0);
+        return Jump();
+    }
+
+    Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        move(imm, immTempRegister);
+        return branchSub32(cond, immTempRegister, dest);
+    }
+
+    // Miscellaneous operations:
+
+    void breakpoint()
+    {
+        m_assembler.bkpt();
+    }
+
+    Call nearCall()
+    {
+        /* We need two words for relaxation.  */
+        m_assembler.nop();
+        m_assembler.nop();
+        m_assembler.jal();
+        m_assembler.nop();
+        return Call(m_assembler.newJmpSrc(), Call::LinkableNear);
+    }
+
+    Call call()
+    {
+        m_assembler.lui(MIPSRegisters::t9, 0);
+        m_assembler.ori(MIPSRegisters::t9, MIPSRegisters::t9, 0);
+        m_assembler.jalr(MIPSRegisters::t9);
+        m_assembler.nop();
+        return Call(m_assembler.newJmpSrc(), Call::Linkable);
+    }
+
+    Call call(RegisterID target)
+    {
+        m_assembler.jalr(target);
+        m_assembler.nop();
+        return Call(m_assembler.newJmpSrc(), Call::None);
+    }
+
+    Call call(Address address)
+    {
+        m_fixedWidth = true;
+        load32(address, MIPSRegisters::t9);
+        m_assembler.jalr(MIPSRegisters::t9);
+        m_assembler.nop();
+        m_fixedWidth = false;
+        return Call(m_assembler.newJmpSrc(), Call::None);
+    }
+
+    void ret()
+    {
+        m_assembler.jr(MIPSRegisters::ra);
+        m_assembler.nop();
+    }
+
+    void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+    {
+        if (cond == Equal || cond == Zero) {
+            m_assembler.xorInsn(dest, left, right);
+            m_assembler.sltiu(dest, dest, 1);
+        } else if (cond == NotEqual || cond == NonZero) {
+            m_assembler.xorInsn(dest, left, right);
+            m_assembler.sltu(dest, MIPSRegisters::zero, dest);
+        } else if (cond == Above)
+            m_assembler.sltu(dest, right, left);
+        else if (cond == AboveOrEqual) {
+            m_assembler.sltu(dest, left, right);
+            m_assembler.xori(dest, dest, 1);
+        } else if (cond == Below)
+            m_assembler.sltu(dest, left, right);
+        else if (cond == BelowOrEqual) {
+            m_assembler.sltu(dest, right, left);
+            m_assembler.xori(dest, dest, 1);
+        } else if (cond == GreaterThan)
+            m_assembler.slt(dest, right, left);
+        else if (cond == GreaterThanOrEqual) {
+            m_assembler.slt(dest, left, right);
+            m_assembler.xori(dest, dest, 1);
+        } else if (cond == LessThan)
+            m_assembler.slt(dest, left, right);
+        else if (cond == LessThanOrEqual) {
+            m_assembler.slt(dest, right, left);
+            m_assembler.xori(dest, dest, 1);
+        } else if (cond == Overflow) {
+            /*
+                xor     cmpTemp, left, right
+                bgez    Done, cmpTemp   # same sign bit -> no overflow
+                move    dest, 0
+                subu    cmpTemp, left, right
+                xor     cmpTemp, cmpTemp, left # diff sign bit -> overflow
+                slt     dest, cmpTemp, 0
+              Done:
+            */
+            m_assembler.xorInsn(cmpTempRegister, left, right);
+            m_assembler.bgez(cmpTempRegister, 4);
+            m_assembler.move(dest, MIPSRegisters::zero);
+            m_assembler.subu(cmpTempRegister, left, right);
+            m_assembler.xorInsn(cmpTempRegister, cmpTempRegister, left);
+            m_assembler.slt(dest, cmpTempRegister, MIPSRegisters::zero);
+        } else if (cond == Signed) {
+            m_assembler.subu(dest, left, right);
+            // Check if the result is negative.
+            m_assembler.slt(dest, dest, MIPSRegisters::zero);
+        }
+    }
+
+    void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+    {
+        move(right, immTempRegister);
+        set32(cond, left, immTempRegister, dest);
+    }
+
+    void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest)
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        load8(address, dataTempRegister);
+        if (mask.m_value == -1 && !m_fixedWidth) {
+            if (cond == Zero)
+                m_assembler.sltiu(dest, dataTempRegister, 1);
+            else
+                m_assembler.sltu(dest, MIPSRegisters::zero, dataTempRegister);
+        } else {
+            move(mask, immTempRegister);
+            m_assembler.andInsn(cmpTempRegister, dataTempRegister,
+                                immTempRegister);
+            if (cond == Zero)
+                m_assembler.sltiu(dest, cmpTempRegister, 1);
+            else
+                m_assembler.sltu(dest, MIPSRegisters::zero, cmpTempRegister);
+        }
+    }
+
+    void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        load32(address, dataTempRegister);
+        if (mask.m_value == -1 && !m_fixedWidth) {
+            if (cond == Zero)
+                m_assembler.sltiu(dest, dataTempRegister, 1);
+            else
+                m_assembler.sltu(dest, MIPSRegisters::zero, dataTempRegister);
+        } else {
+            move(mask, immTempRegister);
+            m_assembler.andInsn(cmpTempRegister, dataTempRegister,
+                                immTempRegister);
+            if (cond == Zero)
+                m_assembler.sltiu(dest, cmpTempRegister, 1);
+            else
+                m_assembler.sltu(dest, MIPSRegisters::zero, cmpTempRegister);
+        }
+    }
+
+    DataLabel32 moveWithPatch(Imm32 imm, RegisterID dest)
+    {
+        m_fixedWidth = true;
+        DataLabel32 label(this);
+        move(imm, dest);
+        m_fixedWidth = false;
+        return label;
+    }
+
+    DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+    {
+        m_fixedWidth = true;
+        DataLabelPtr label(this);
+        move(initialValue, dest);
+        m_fixedWidth = false;
+        return label;
+    }
+
+    Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        m_fixedWidth = true;
+        dataLabel = moveWithPatch(initialRightValue, immTempRegister);
+        Jump temp = branch32(cond, left, immTempRegister);
+        m_fixedWidth = false;
+        return temp;
+    }
+
+    Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        m_fixedWidth = true;
+        load32(left, dataTempRegister);
+        dataLabel = moveWithPatch(initialRightValue, immTempRegister);
+        Jump temp = branch32(cond, dataTempRegister, immTempRegister);
+        m_fixedWidth = false;
+        return temp;
+    }
+
+    DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+    {
+        m_fixedWidth = true;
+        DataLabelPtr dataLabel = moveWithPatch(initialValue, dataTempRegister);
+        store32(dataTempRegister, address);
+        m_fixedWidth = false;
+        return dataLabel;
+    }
+
+    DataLabelPtr storePtrWithPatch(ImplicitAddress address)
+    {
+        return storePtrWithPatch(ImmPtr(0), address);
+    }
+
+    Call tailRecursiveCall()
+    {
+        // Like a normal call, but don't update the returned address register
+        m_fixedWidth = true;
+        move(Imm32(0), MIPSRegisters::t9);
+        m_assembler.jr(MIPSRegisters::t9);
+        m_assembler.nop();
+        m_fixedWidth = false;
+        return Call(m_assembler.newJmpSrc(), Call::Linkable);
+    }
+
+    Call makeTailRecursiveCall(Jump oldJump)
+    {
+        oldJump.link(this);
+        return tailRecursiveCall();
+    }
+
+    void loadDouble(ImplicitAddress address, FPRegisterID dest)
+    {
+#if WTF_MIPS_ISA(1)
+        /*
+            li          addrTemp, address.offset
+            addu        addrTemp, addrTemp, base
+            lwc1        dest, 0(addrTemp)
+            lwc1        dest+1, 4(addrTemp)
+         */
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.lwc1(dest, addrTempRegister, 0);
+        m_assembler.lwc1(FPRegisterID(dest + 1), addrTempRegister, 4);
+#else
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            m_assembler.ldc1(dest, address.base, address.offset);
+        } else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                ldc1    dest, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.ldc1(dest, addrTempRegister, address.offset);
+        }
+#endif
+    }
+
+    void storeDouble(FPRegisterID src, ImplicitAddress address)
+    {
+#if WTF_MIPS_ISA(1)
+        /*
+            li          addrTemp, address.offset
+            addu        addrTemp, addrTemp, base
+            swc1        dest, 0(addrTemp)
+            swc1        dest+1, 4(addrTemp)
+         */
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.swc1(src, addrTempRegister, 0);
+        m_assembler.swc1(FPRegisterID(src + 1), addrTempRegister, 4);
+#else
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth)
+            m_assembler.sdc1(src, address.base, address.offset);
+        else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                sdc1    src, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.sdc1(src, addrTempRegister, address.offset);
+        }
+#endif
+    }
+
+    void addDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.addd(dest, dest, src);
+    }
+
+    void addDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        m_assembler.addd(dest, dest, fpTempRegister);
+    }
+
+    void subDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.subd(dest, dest, src);
+    }
+
+    void subDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        m_assembler.subd(dest, dest, fpTempRegister);
+    }
+
+    void mulDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.muld(dest, dest, src);
+    }
+
+    void mulDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        m_assembler.muld(dest, dest, fpTempRegister);
+    }
+
+    void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
+    {
+        m_assembler.mtc1(src, fpTempRegister);
+        m_assembler.cvtdw(dest, fpTempRegister);
+    }
+
+    void insertRelaxationWords()
+    {
+        /* We need four words for relaxation. */
+        m_assembler.beq(MIPSRegisters::zero, MIPSRegisters::zero, 3); // Jump over nops;
+        m_assembler.nop();
+        m_assembler.nop();
+        m_assembler.nop();
+    }
+
+    Jump branchTrue()
+    {
+        m_assembler.appendJump();
+        m_assembler.bc1t();
+        m_assembler.nop();
+        insertRelaxationWords();
+        return Jump(m_assembler.newJmpSrc());
+    }
+
+    Jump branchFalse()
+    {
+        m_assembler.appendJump();
+        m_assembler.bc1f();
+        m_assembler.nop();
+        insertRelaxationWords();
+        return Jump(m_assembler.newJmpSrc());
+    }
+
+    Jump branchEqual(RegisterID rs, RegisterID rt)
+    {
+        m_assembler.appendJump();
+        m_assembler.beq(rs, rt, 0);
+        m_assembler.nop();
+        insertRelaxationWords();
+        return Jump(m_assembler.newJmpSrc());
+    }
+
+    Jump branchNotEqual(RegisterID rs, RegisterID rt)
+    {
+        m_assembler.appendJump();
+        m_assembler.bne(rs, rt, 0);
+        m_assembler.nop();
+        insertRelaxationWords();
+        return Jump(m_assembler.newJmpSrc());
+    }
+
+    Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
+    {
+        if (cond == DoubleEqual) {
+            m_assembler.ceqd(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleNotEqual) {
+            m_assembler.ceqd(left, right);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleGreaterThan) {
+            m_assembler.cngtd(left, right);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleGreaterThanOrEqual) {
+            m_assembler.cnged(right, left);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleLessThan) {
+            m_assembler.cltd(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleLessThanOrEqual) {
+            m_assembler.cled(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleEqualOrUnordered) {
+            m_assembler.cueqd(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleGreaterThanOrUnordered) {
+            m_assembler.coled(left, right);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleGreaterThanOrEqualOrUnordered) {
+            m_assembler.coltd(left, right);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleLessThanOrUnordered) {
+            m_assembler.cultd(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleLessThanOrEqualOrUnordered) {
+            m_assembler.culed(left, right);
+            return branchTrue();
+        }
+        ASSERT(0);
+
+        return Jump();
+    }
+
+    // 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_MAX 0x7fffffff).
+    Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.truncwd(fpTempRegister, src);
+        m_assembler.mfc1(dest, fpTempRegister);
+        return branch32(Equal, dest, Imm32(0x7fffffff));
+    }
+
+private:
+    // If m_fixedWidth is true, we will generate a fixed number of instructions.
+    // Otherwise, we can emit any number of instructions.
+    bool m_fixedWidth;
+
+    friend class LinkBuffer;
+    friend class RepatchBuffer;
+
+    static void linkCall(void* code, Call call, FunctionPtr function)
+    {
+        MIPSAssembler::linkCall(code, call.m_jmp, function.value());
+    }
+
+    static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
+    {
+        MIPSAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
+    }
+
+    static void repatchCall(CodeLocationCall call, FunctionPtr destination)
+    {
+        MIPSAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
+    }
+
+};
+
+}
+
+#endif // ENABLE(ASSEMBLER) && CPU(MIPS)
+
+#endif // MacroAssemblerMIPS_h
index ca7c31a0796a4b65caf324647d898b5dfd5d520f..0918996302022e211db69da6a2cd08f82f145d6b 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef MacroAssemblerX86_h
 #define MacroAssemblerX86_h
 
 #ifndef MacroAssemblerX86_h
 #define MacroAssemblerX86_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER) && CPU(X86)
 
 #include "MacroAssemblerX86Common.h"
 #if ENABLE(ASSEMBLER) && CPU(X86)
 
 #include "MacroAssemblerX86Common.h"
@@ -89,7 +87,7 @@ public:
         m_assembler.movl_mr(address, dest);
     }
 
         m_assembler.movl_mr(address, dest);
     }
 
-    void loadDouble(void* address, FPRegisterID dest)
+    void loadDouble(const void* address, FPRegisterID dest)
     {
         ASSERT(isSSE2Present());
         m_assembler.movsd_mr(address, dest);
     {
         ASSERT(isSSE2Present());
         m_assembler.movsd_mr(address, dest);
@@ -174,6 +172,7 @@ public:
     bool supportsFloatingPoint() const { return m_isSSE2Present; }
     // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
     bool supportsFloatingPointTruncate() const { return m_isSSE2Present; }
     bool supportsFloatingPoint() const { return m_isSSE2Present; }
     // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
     bool supportsFloatingPointTruncate() const { return m_isSSE2Present; }
+    bool supportsFloatingPointSqrt() const { return m_isSSE2Present; }
 
 private:
     const bool m_isSSE2Present;
 
 private:
     const bool m_isSSE2Present;
index 449df86c6673790f8a7f6e0b17a699c0ab646c9c..cb86da7e4589d7b6d29cf2ecaf388c7cb61f1f3b 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef MacroAssemblerX86Common_h
 #define MacroAssemblerX86Common_h
 
 #ifndef MacroAssemblerX86Common_h
 #define MacroAssemblerX86Common_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER)
 
 #include "X86Assembler.h"
 #if ENABLE(ASSEMBLER)
 
 #include "X86Assembler.h"
@@ -41,6 +39,7 @@ class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
     static const int DoubleConditionBits = DoubleConditionBitInvert | DoubleConditionBitSpecial;
 
 public:
     static const int DoubleConditionBits = DoubleConditionBitInvert | DoubleConditionBitSpecial;
 
 public:
+    typedef X86Assembler::FPRegisterID FPRegisterID;
 
     enum Condition {
         Equal = X86Assembler::ConditionE,
 
     enum Condition {
         Equal = X86Assembler::ConditionE,
@@ -251,6 +250,33 @@ public:
     {
         m_assembler.sarl_i8r(imm.m_value, dest);
     }
     {
         m_assembler.sarl_i8r(imm.m_value, dest);
     }
+    
+    void urshift32(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 != X86Registers::ecx) {
+            swap(shift_amount, X86Registers::ecx);
+            
+            // E.g. transform "shrl %eax, %eax" -> "xchgl %eax, %ecx; shrl %ecx, %ecx; xchgl %eax, %ecx"
+            if (dest == shift_amount)
+                m_assembler.shrl_CLr(X86Registers::ecx);
+            // E.g. transform "shrl %eax, %ecx" -> "xchgl %eax, %ecx; shrl %ecx, %eax; xchgl %eax, %ecx"
+            else if (dest == X86Registers::ecx)
+                m_assembler.shrl_CLr(shift_amount);
+            // E.g. transform "shrl %eax, %ebx" -> "xchgl %eax, %ecx; shrl %ecx, %ebx; xchgl %eax, %ecx"
+            else
+                m_assembler.shrl_CLr(dest);
+            
+            swap(shift_amount, X86Registers::ecx);
+        } else
+            m_assembler.shrl_CLr(dest);
+    }
+    
+    void urshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.shrl_i8r(imm.m_value, dest);
+    }
 
     void sub32(RegisterID src, RegisterID dest)
     {
 
     void sub32(RegisterID src, RegisterID dest)
     {
@@ -303,6 +329,10 @@ public:
         m_assembler.xorl_mr(src.offset, src.base, dest);
     }
     
         m_assembler.xorl_mr(src.offset, src.base, dest);
     }
     
+    void sqrtDouble(FPRegisterID src, FPRegisterID dst)
+    {
+        m_assembler.sqrtsd_rr(src, dst);
+    }
 
     // Memory access operations:
     //
 
     // Memory access operations:
     //
@@ -336,6 +366,11 @@ public:
     {
         m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest);
     }
     {
         m_assembler.movzwl_mr(address.offset, address.base, address.index, address.scale, dest);
     }
+    
+    void load16(Address address, RegisterID dest)
+    {
+        m_assembler.movzwl_mr(address.offset, address.base, dest);
+    }
 
     DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
     {
 
     DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
     {
@@ -620,6 +655,12 @@ public:
     // an optional second operand of a mask under which to perform the test.
 
 public:
     // an optional second operand of a mask under which to perform the test.
 
 public:
+    Jump branch8(Condition cond, Address left, Imm32 right)
+    {
+        m_assembler.cmpb_im(right.m_value, left.offset, left.base);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
     Jump branch32(Condition cond, RegisterID left, RegisterID right)
     {
         m_assembler.cmpl_rr(right, left);
     Jump branch32(Condition cond, RegisterID left, RegisterID right)
     {
         m_assembler.cmpl_rr(right, left);
@@ -717,6 +758,26 @@ public:
             m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
         return Jump(m_assembler.jCC(x86Condition(cond)));
     }
             m_assembler.testl_i32m(mask.m_value, address.offset, address.base, address.index, address.scale);
         return Jump(m_assembler.jCC(x86Condition(cond)));
     }
+    
+    Jump branchTest8(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        if (mask.m_value == -1)
+            m_assembler.cmpb_im(0, address.offset, address.base);
+        else
+            m_assembler.testb_im(mask.m_value, address.offset, address.base);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+    
+    Jump branchTest8(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        if (mask.m_value == -1)
+            m_assembler.cmpb_im(0, address.offset, address.base, address.index, address.scale);
+        else
+            m_assembler.testb_im(mask.m_value, address.offset, address.base, address.index, address.scale);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
 
     Jump jump()
     {
 
     Jump jump()
     {
@@ -836,6 +897,13 @@ public:
         return Jump(m_assembler.jCC(x86Condition(cond)));
     }
 
         return Jump(m_assembler.jCC(x86Condition(cond)));
     }
 
+    Jump branchNeg32(Condition cond, RegisterID srcDest)
+    {
+        ASSERT((cond == Overflow) || (cond == Zero) || (cond == NonZero));
+        neg32(srcDest);
+        return Jump(m_assembler.jCC(x86Condition(cond)));
+    }
+
     Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
     {
         ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
     Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
     {
         ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
@@ -917,10 +985,11 @@ public:
     void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest)
     {
         if (mask.m_value == -1)
     void setTest8(Condition cond, Address address, Imm32 mask, RegisterID dest)
     {
         if (mask.m_value == -1)
-            m_assembler.cmpl_im(0, address.offset, address.base);
+            m_assembler.cmpb_im(0, address.offset, address.base);
         else
         else
-            m_assembler.testl_i32m(mask.m_value, address.offset, address.base);
+            m_assembler.testb_im(mask.m_value, address.offset, address.base);
         m_assembler.setCC_r(x86Condition(cond), dest);
         m_assembler.setCC_r(x86Condition(cond), dest);
+        m_assembler.movzbl_rr(dest, dest);
     }
 
     void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
     }
 
     void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
index ec93f8c657851e970d689819780e19a24836f53a..168c93f650d1d501e2087a57014584e734b610c2 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef MacroAssemblerX86_64_h
 #define MacroAssemblerX86_64_h
 
 #ifndef MacroAssemblerX86_64_h
 #define MacroAssemblerX86_64_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER) && CPU(X86_64)
 
 #include "MacroAssemblerX86Common.h"
 #if ENABLE(ASSEMBLER) && CPU(X86_64)
 
 #include "MacroAssemblerX86Common.h"
@@ -88,7 +86,7 @@ public:
         }
     }
 
         }
     }
 
-    void loadDouble(void* address, FPRegisterID dest)
+    void loadDouble(const void* address, FPRegisterID dest)
     {
         move(ImmPtr(address), scratchRegister);
         loadDouble(scratchRegister, dest);
     {
         move(ImmPtr(address), scratchRegister);
         loadDouble(scratchRegister, dest);
@@ -411,6 +409,14 @@ public:
         return label;
     }
 
         return label;
     }
 
+    using MacroAssemblerX86Common::branchTest8;
+    Jump branchTest8(Condition cond, ExtendedAddress address, Imm32 mask = Imm32(-1))
+    {
+        ImmPtr addr(reinterpret_cast<void*>(address.offset));
+        MacroAssemblerX86Common::move(addr, scratchRegister);
+        return MacroAssemblerX86Common::branchTest8(cond, BaseIndex(scratchRegister, address.base, TimesOne), mask);
+    }
+
     Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
     {
         Label label(this);
     Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
     {
         Label label(this);
@@ -421,6 +427,7 @@ public:
     bool supportsFloatingPoint() const { return true; }
     // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
     bool supportsFloatingPointTruncate() const { return true; }
     bool supportsFloatingPoint() const { return true; }
     // See comment on MacroAssemblerARMv7::supportsFloatingPointTruncate()
     bool supportsFloatingPointTruncate() const { return true; }
+    bool supportsFloatingPointSqrt() const { return true; }
 
 private:
     friend class LinkBuffer;
 
 private:
     friend class LinkBuffer;
index 89cbf06d1ab283fb83b357476a1b4aa2b7801bbd..72cf6b27f09e3507e9cdfec0c7cff904260cc03f 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef RepatchBuffer_h
 #define RepatchBuffer_h
 
 #ifndef RepatchBuffer_h
 #define RepatchBuffer_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER)
 
 #include <MacroAssembler.h>
 #if ENABLE(ASSEMBLER)
 
 #include <MacroAssembler.h>
index ab3d05f181d320511adcf5e5f9df2c0bc00b75b2..20d72f5a55873df164e4fb1a2906cfd695086e35 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef X86Assembler_h
 #define X86Assembler_h
 
 #ifndef X86Assembler_h
 #define X86Assembler_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
 
 #include "AssemblerBuffer.h"
 #if ENABLE(ASSEMBLER) && (CPU(X86) || CPU(X86_64))
 
 #include "AssemblerBuffer.h"
@@ -130,6 +128,7 @@ private:
         PRE_SSE_66                      = 0x66,
         OP_PUSH_Iz                      = 0x68,
         OP_IMUL_GvEvIz                  = 0x69,
         PRE_SSE_66                      = 0x66,
         OP_PUSH_Iz                      = 0x68,
         OP_IMUL_GvEvIz                  = 0x69,
+        OP_GROUP1_EbIb                  = 0x80,
         OP_GROUP1_EvIz                  = 0x81,
         OP_GROUP1_EvIb                  = 0x83,
         OP_TEST_EvGv                    = 0x85,
         OP_GROUP1_EvIz                  = 0x81,
         OP_GROUP1_EvIb                  = 0x83,
         OP_TEST_EvGv                    = 0x85,
@@ -168,6 +167,7 @@ private:
         OP2_MULSD_VsdWsd    = 0x59,
         OP2_SUBSD_VsdWsd    = 0x5C,
         OP2_DIVSD_VsdWsd    = 0x5E,
         OP2_MULSD_VsdWsd    = 0x59,
         OP2_SUBSD_VsdWsd    = 0x5C,
         OP2_DIVSD_VsdWsd    = 0x5E,
+        OP2_SQRTSD_VsdWsd   = 0x51,
         OP2_XORPD_VpdWpd    = 0x57,
         OP2_MOVD_VdEd       = 0x6E,
         OP2_MOVD_EdVd       = 0x7E,
         OP2_XORPD_VpdWpd    = 0x57,
         OP2_MOVD_VdEd       = 0x6E,
         OP2_MOVD_EdVd       = 0x7E,
@@ -201,6 +201,7 @@ private:
         GROUP1A_OP_POP = 0,
 
         GROUP2_OP_SHL = 4,
         GROUP1A_OP_POP = 0,
 
         GROUP2_OP_SHL = 4,
+        GROUP2_OP_SHR = 5,
         GROUP2_OP_SAR = 7,
 
         GROUP3_OP_TEST = 0,
         GROUP2_OP_SAR = 7,
 
         GROUP3_OP_TEST = 0,
@@ -673,6 +674,21 @@ public:
     {
         m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
     }
     {
         m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SAR, dst);
     }
+    
+    void shrl_i8r(int imm, RegisterID dst)
+    {
+        if (imm == 1)
+            m_formatter.oneByteOp(OP_GROUP2_Ev1, GROUP2_OP_SHR, dst);
+        else {
+            m_formatter.oneByteOp(OP_GROUP2_EvIb, GROUP2_OP_SHR, dst);
+            m_formatter.immediate8(imm);
+        }
+    }
+    
+    void shrl_CLr(RegisterID dst)
+    {
+        m_formatter.oneByteOp(OP_GROUP2_EvCL, GROUP2_OP_SHR, dst);
+    }
 
     void shll_i8r(int imm, RegisterID dst)
     {
 
     void shll_i8r(int imm, RegisterID dst)
     {
@@ -760,7 +776,7 @@ public:
         m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
         m_formatter.immediate32(imm);
     }
         m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, dst);
         m_formatter.immediate32(imm);
     }
-
+    
     void cmpl_im(int imm, int offset, RegisterID base)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
     void cmpl_im(int imm, int offset, RegisterID base)
     {
         if (CAN_SIGN_EXTEND_8_32(imm)) {
@@ -771,6 +787,18 @@ public:
             m_formatter.immediate32(imm);
         }
     }
             m_formatter.immediate32(imm);
         }
     }
+    
+    void cmpb_im(int imm, int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, offset);
+        m_formatter.immediate8(imm);
+    }
+    
+    void cmpb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
+    {
+        m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, base, index, scale, offset);
+        m_formatter.immediate8(imm);
+    }
 
     void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
     {
 
     void cmpl_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
     {
@@ -890,6 +918,18 @@ public:
         m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
         m_formatter.immediate32(imm);
     }
         m_formatter.oneByteOp(OP_GROUP3_EvIz, GROUP3_OP_TEST, base, offset);
         m_formatter.immediate32(imm);
     }
+    
+    void testb_im(int imm, int offset, RegisterID base)
+    {
+        m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, offset);
+        m_formatter.immediate8(imm);
+    }
+    
+    void testb_im(int imm, int offset, RegisterID base, RegisterID index, int scale)
+    {
+        m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, base, index, scale, offset);
+        m_formatter.immediate8(imm);
+    }
 
     void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
     {
 
     void testl_i32m(int imm, int offset, RegisterID base, RegisterID index, int scale)
     {
@@ -1370,7 +1410,7 @@ public:
     }
 
 #if !CPU(X86_64)
     }
 
 #if !CPU(X86_64)
-    void movsd_mr(void* address, XMMRegisterID dst)
+    void movsd_mr(const void* address, XMMRegisterID dst)
     {
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
     {
         m_formatter.prefix(PRE_SSE_F2);
         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
@@ -1438,6 +1478,12 @@ public:
         m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
     }
 
         m_formatter.twoByteOp(OP2_XORPD_VpdWpd, (RegisterID)dst, (RegisterID)src);
     }
 
+    void sqrtsd_rr(XMMRegisterID src, XMMRegisterID dst)
+    {
+        m_formatter.prefix(PRE_SSE_F2);
+        m_formatter.twoByteOp(OP2_SQRTSD_VsdWsd, (RegisterID)dst, (RegisterID)src);
+    }
+
     // Misc instructions:
 
     void int3()
     // Misc instructions:
 
     void int3()
@@ -1723,7 +1769,7 @@ private:
         }
 
 #if !CPU(X86_64)
         }
 
 #if !CPU(X86_64)
-        void twoByteOp(TwoByteOpcodeID opcode, int reg, void* address)
+        void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
         {
             m_buffer.ensureSpace(maxInstructionSize);
             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
         {
             m_buffer.ensureSpace(maxInstructionSize);
             m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
@@ -2034,7 +2080,7 @@ private:
         }
 
 #if !CPU(X86_64)
         }
 
 #if !CPU(X86_64)
-        void memoryModRM(int reg, void* address)
+        void memoryModRM(int reg, const void* address)
         {
             // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
             putModRm(ModRmMemoryNoDisp, reg, noBase);
         {
             // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
             putModRm(ModRmMemoryNoDisp, reg, noBase);
index fd56ece666c7788b1260aed3a2ab04eed264bd9b..8cefb1ba9adfe2d3ee9a032acdf9b6f0619ae747 100644 (file)
@@ -49,8 +49,8 @@ namespace JSC {
 static UString escapeQuotes(const UString& str)
 {
     UString result = str;
 static UString escapeQuotes(const UString& str)
 {
     UString result = str;
-    int pos = 0;
-    while ((pos = result.find('\"', pos)) >= 0) {
+    unsigned pos = 0;
+    while ((pos = result.find('\"', pos)) != UString::NotFound) {
         result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1));
         pos += 4;
     }
         result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1));
         pos += 4;
     }
@@ -141,7 +141,7 @@ void CodeBlock::printUnaryOp(ExecState* exec, int location, Vector<Instruction>:
     int r0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
 
     int r0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
 
-    printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str());
+    printf("[%4d] %s\t\t %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data());
 }
 
 void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
 }
 
 void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
@@ -149,14 +149,14 @@ void CodeBlock::printBinaryOp(ExecState* exec, int location, Vector<Instruction>
     int r0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
     int r2 = (++it)->u.operand;
     int r0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
     int r2 = (++it)->u.operand;
-    printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str());
+    printf("[%4d] %s\t\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
 }
 
 void CodeBlock::printConditionalJump(ExecState* exec, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op) const
 {
     int r0 = (++it)->u.operand;
     int offset = (++it)->u.operand;
 }
 
 void CodeBlock::printConditionalJump(ExecState* exec, const Vector<Instruction>::const_iterator&, Vector<Instruction>::const_iterator& it, int location, const char* op) const
 {
     int r0 = (++it)->u.operand;
     int offset = (++it)->u.operand;
-    printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).c_str(), offset, location + offset);
+    printf("[%4d] %s\t\t %s, %d(->%d)\n", location, op, registerName(exec, r0).data(), offset, location + offset);
 }
 
 void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
 }
 
 void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector<Instruction>::const_iterator& it, const char* op) const
@@ -164,7 +164,7 @@ void CodeBlock::printGetByIdOp(ExecState* exec, int location, Vector<Instruction
     int r0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
     int id0 = (++it)->u.operand;
     int r0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
     int id0 = (++it)->u.operand;
-    printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
+    printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
     it += 4;
 }
 
     it += 4;
 }
 
@@ -173,14 +173,14 @@ void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vector<Instruction
     int r0 = (++it)->u.operand;
     int id0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
     int r0 = (++it)->u.operand;
     int id0 = (++it)->u.operand;
     int r1 = (++it)->u.operand;
-    printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str());
+    printf("[%4d] %s\t %s, %s, %s\n", location, op, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
     it += 4;
 }
 
 #if ENABLE(JIT)
 static bool isGlobalResolve(OpcodeID opcodeID)
 {
     it += 4;
 }
 
 #if ENABLE(JIT)
 static bool isGlobalResolve(OpcodeID opcodeID)
 {
-    return opcodeID == op_resolve_global;
+    return opcodeID == op_resolve_global || opcodeID == op_resolve_global_dynamic;
 }
 
 static bool isPropertyAccess(OpcodeID opcodeID)
 }
 
 static bool isPropertyAccess(OpcodeID opcodeID)
@@ -223,32 +223,32 @@ static unsigned instructionOffsetForNth(ExecState* exec, const Vector<Instructio
 
 static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigned instructionOffset)
 {
 
 static void printGlobalResolveInfo(const GlobalResolveInfo& resolveInfo, unsigned instructionOffset)
 {
-    printf("  [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).UTF8String().c_str());
+    printf("  [%4d] %s: %s\n", instructionOffset, "resolve_global", pointerToSourceString(resolveInfo.structure).UTF8String().data());
 }
 
 static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset)
 {
     switch (stubInfo.accessType) {
     case access_get_by_id_self:
 }
 
 static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned instructionOffset)
 {
     switch (stubInfo.accessType) {
     case access_get_by_id_self:
-        printf("  [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().c_str());
+        printf("  [%4d] %s: %s\n", instructionOffset, "get_by_id_self", pointerToSourceString(stubInfo.u.getByIdSelf.baseObjectStructure).UTF8String().data());
         return;
     case access_get_by_id_proto:
         return;
     case access_get_by_id_proto:
-        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().c_str());
+        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(stubInfo.u.getByIdProto.baseObjectStructure).UTF8String().data(), pointerToSourceString(stubInfo.u.getByIdProto.prototypeStructure).UTF8String().data());
         return;
     case access_get_by_id_chain:
         return;
     case access_get_by_id_chain:
-        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().c_str());
+        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(stubInfo.u.getByIdChain.baseObjectStructure).UTF8String().data(), pointerToSourceString(stubInfo.u.getByIdChain.chain).UTF8String().data());
         return;
     case access_get_by_id_self_list:
         return;
     case access_get_by_id_self_list:
-        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).UTF8String().c_str(), stubInfo.u.getByIdSelfList.listSize);
+        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_self_list", pointerToSourceString(stubInfo.u.getByIdSelfList.structureList).UTF8String().data(), stubInfo.u.getByIdSelfList.listSize);
         return;
     case access_get_by_id_proto_list:
         return;
     case access_get_by_id_proto_list:
-        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).UTF8String().c_str(), stubInfo.u.getByIdProtoList.listSize);
+        printf("  [%4d] %s: %s (%d)\n", instructionOffset, "op_get_by_id_proto_list", pointerToSourceString(stubInfo.u.getByIdProtoList.structureList).UTF8String().data(), stubInfo.u.getByIdProtoList.listSize);
         return;
     case access_put_by_id_transition:
         return;
     case access_put_by_id_transition:
-        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().c_str(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().c_str());
+        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(stubInfo.u.putByIdTransition.previousStructure).UTF8String().data(), pointerToSourceString(stubInfo.u.putByIdTransition.structure).UTF8String().data(), pointerToSourceString(stubInfo.u.putByIdTransition.chain).UTF8String().data());
         return;
     case access_put_by_id_replace:
         return;
     case access_put_by_id_replace:
-        printf("  [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().c_str());
+        printf("  [%4d] %s: %s\n", instructionOffset, "put_by_id_replace", pointerToSourceString(stubInfo.u.putByIdReplace.baseObjectStructure).UTF8String().data());
         return;
     case access_get_by_id:
         printf("  [%4d] %s\n", instructionOffset, "get_by_id");
         return;
     case access_get_by_id:
         printf("  [%4d] %s\n", instructionOffset, "get_by_id");
@@ -277,7 +277,7 @@ static void printStructureStubInfo(const StructureStubInfo& stubInfo, unsigned i
 void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand) const
 {
     unsigned instructionOffset = vPC - m_instructions.begin();
 void CodeBlock::printStructure(const char* name, const Instruction* vPC, int operand) const
 {
     unsigned instructionOffset = vPC - m_instructions.begin();
-    printf("  [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).UTF8String().c_str());
+    printf("  [%4d] %s: %s\n", instructionOffset, name, pointerToSourceString(vPC[operand].u.structure).UTF8String().data());
 }
 
 void CodeBlock::printStructures(const Instruction* vPC) const
 }
 
 void CodeBlock::printStructures(const Instruction* vPC) const
@@ -294,15 +294,15 @@ void CodeBlock::printStructures(const Instruction* vPC) const
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
-        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structure).UTF8String().c_str());
+        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_proto", pointerToSourceString(vPC[4].u.structure).UTF8String().data(), pointerToSourceString(vPC[5].u.structure).UTF8String().data());
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_transition)) {
-        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[6].u.structureChain).UTF8String().c_str());
+        printf("  [%4d] %s: %s, %s, %s\n", instructionOffset, "put_by_id_transition", pointerToSourceString(vPC[4].u.structure).UTF8String().data(), pointerToSourceString(vPC[5].u.structure).UTF8String().data(), pointerToSourceString(vPC[6].u.structureChain).UTF8String().data());
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
-        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).UTF8String().c_str(), pointerToSourceString(vPC[5].u.structureChain).UTF8String().c_str());
+        printf("  [%4d] %s: %s, %s\n", instructionOffset, "get_by_id_chain", pointerToSourceString(vPC[4].u.structure).UTF8String().data(), pointerToSourceString(vPC[5].u.structureChain).UTF8String().data());
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) {
         return;
     }
     if (vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id)) {
@@ -317,6 +317,10 @@ void CodeBlock::printStructures(const Instruction* vPC) const
         printStructure("resolve_global", vPC, 4);
         return;
     }
         printStructure("resolve_global", vPC, 4);
         return;
     }
+    if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global_dynamic)) {
+        printStructure("resolve_global_dynamic", vPC, 4);
+        return;
+    }
 
     // These m_instructions doesn't ref Structures.
     ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));
 
     // These m_instructions doesn't ref Structures.
     ASSERT(vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_put_by_id_generic) || vPC[0].u.opcode == interpreter->getOpcode(op_call) || vPC[0].u.opcode == interpreter->getOpcode(op_call_eval) || vPC[0].u.opcode == interpreter->getOpcode(op_construct));
@@ -482,7 +486,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_enter_with_activation: {
             int r0 = (++it)->u.operand;
         }
         case op_enter_with_activation: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] enter_with_activation %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] enter_with_activation %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_create_arguments: {
             break;
         }
         case op_create_arguments: {
@@ -495,31 +499,31 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_convert_this: {
             int r0 = (++it)->u.operand;
         }
         case op_convert_this: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] convert_this %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] convert_this %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_new_object: {
             int r0 = (++it)->u.operand;
             break;
         }
         case op_new_object: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] new_object\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] new_object\t %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_new_array: {
             int dst = (++it)->u.operand;
             int argv = (++it)->u.operand;
             int argc = (++it)->u.operand;
             break;
         }
         case op_new_array: {
             int dst = (++it)->u.operand;
             int argv = (++it)->u.operand;
             int argc = (++it)->u.operand;
-            printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, argv).c_str(), argc);
+            printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
             break;
         }
         case op_new_regexp: {
             int r0 = (++it)->u.operand;
             int re0 = (++it)->u.operand;
             break;
         }
         case op_new_regexp: {
             int r0 = (++it)->u.operand;
             int re0 = (++it)->u.operand;
-            printf("[%4d] new_regexp\t %s, %s\n", location, registerName(exec, r0).c_str(), regexpName(re0, regexp(re0)).c_str());
+            printf("[%4d] new_regexp\t %s, %s\n", location, registerName(exec, r0).data(), regexpName(re0, regexp(re0)).data());
             break;
         }
         case op_mov: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             break;
         }
         case op_mov: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
-            printf("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str());
+            printf("[%4d] mov\t\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data());
             break;
         }
         case op_not: {
             break;
         }
         case op_not: {
@@ -560,12 +564,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_pre_inc: {
             int r0 = (++it)->u.operand;
         }
         case op_pre_inc: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] pre_inc\t\t %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_pre_dec: {
             int r0 = (++it)->u.operand;
             break;
         }
         case op_pre_dec: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] pre_dec\t\t %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_post_inc: {
             break;
         }
         case op_post_inc: {
@@ -644,7 +648,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
             int r3 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
             int r3 = (++it)->u.operand;
-            printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str());
+            printf("[%4d] instanceof\t\t %s, %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data());
             break;
         }
         case op_typeof: {
             break;
         }
         case op_typeof: {
@@ -682,63 +686,72 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         case op_resolve: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
         case op_resolve: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
-            printf("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str());
+            printf("[%4d] resolve\t\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
             break;
         }
         case op_resolve_skip: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int skipLevels = (++it)->u.operand;
             break;
         }
         case op_resolve_skip: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int skipLevels = (++it)->u.operand;
-            printf("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), skipLevels);
+            printf("[%4d] resolve_skip\t %s, %s, %d\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), skipLevels);
             break;
         }
         case op_resolve_global: {
             int r0 = (++it)->u.operand;
             JSValue scope = JSValue((++it)->u.jsCell);
             int id0 = (++it)->u.operand;
             break;
         }
         case op_resolve_global: {
             int r0 = (++it)->u.operand;
             JSValue scope = JSValue((++it)->u.jsCell);
             int id0 = (++it)->u.operand;
-            printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).c_str());
+            printf("[%4d] resolve_global\t %s, %s, %s\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).data());
             it += 2;
             break;
         }
             it += 2;
             break;
         }
+        case op_resolve_global_dynamic: {
+            int r0 = (++it)->u.operand;
+            JSValue scope = JSValue((++it)->u.jsCell);
+            int id0 = (++it)->u.operand;
+            int depth = it[2].u.operand;
+            printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).ascii(), idName(id0, m_identifiers[id0]).data(), depth);
+            it += 3;
+            break;
+        }
         case op_get_scoped_var: {
             int r0 = (++it)->u.operand;
             int index = (++it)->u.operand;
             int skipLevels = (++it)->u.operand;
         case op_get_scoped_var: {
             int r0 = (++it)->u.operand;
             int index = (++it)->u.operand;
             int skipLevels = (++it)->u.operand;
-            printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).c_str(), index, skipLevels);
+            printf("[%4d] get_scoped_var\t %s, %d, %d\n", location, registerName(exec, r0).data(), index, skipLevels);
             break;
         }
         case op_put_scoped_var: {
             int index = (++it)->u.operand;
             int skipLevels = (++it)->u.operand;
             int r0 = (++it)->u.operand;
             break;
         }
         case op_put_scoped_var: {
             int index = (++it)->u.operand;
             int skipLevels = (++it)->u.operand;
             int r0 = (++it)->u.operand;
-            printf("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).c_str());
+            printf("[%4d] put_scoped_var\t %d, %d, %s\n", location, index, skipLevels, registerName(exec, r0).data());
             break;
         }
         case op_get_global_var: {
             int r0 = (++it)->u.operand;
             JSValue scope = JSValue((++it)->u.jsCell);
             int index = (++it)->u.operand;
             break;
         }
         case op_get_global_var: {
             int r0 = (++it)->u.operand;
             JSValue scope = JSValue((++it)->u.jsCell);
             int index = (++it)->u.operand;
-            printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), valueToSourceString(exec, scope).ascii(), index);
+            printf("[%4d] get_global_var\t %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).ascii(), index);
             break;
         }
         case op_put_global_var: {
             JSValue scope = JSValue((++it)->u.jsCell);
             int index = (++it)->u.operand;
             int r0 = (++it)->u.operand;
             break;
         }
         case op_put_global_var: {
             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(exec, r0).c_str());
+            printf("[%4d] put_global_var\t %s, %d, %s\n", location, valueToSourceString(exec, scope).ascii(), index, registerName(exec, r0).data());
             break;
         }
         case op_resolve_base: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             break;
         }
         case op_resolve_base: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
-            printf("[%4d] resolve_base\t %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str());
+            printf("[%4d] resolve_base\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data());
             break;
         }
         case op_resolve_with_base: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             break;
         }
         case op_resolve_with_base: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
-            printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
+            printf("[%4d] resolve_with_base %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
             break;
         }
         case op_get_by_id: {
             break;
         }
         case op_get_by_id: {
@@ -765,6 +778,46 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             printGetByIdOp(exec, location, it, "get_by_id_chain");
             break;
         }
             printGetByIdOp(exec, location, it, "get_by_id_chain");
             break;
         }
+        case op_get_by_id_getter_self: {
+            printGetByIdOp(exec, location, it, "get_by_id_getter_self");
+            break;
+        }
+        case op_get_by_id_getter_self_list: {
+            printGetByIdOp(exec, location, it, "get_by_id_getter_self_list");
+            break;
+        }
+        case op_get_by_id_getter_proto: {
+            printGetByIdOp(exec, location, it, "get_by_id_getter_proto");
+            break;
+        }
+        case op_get_by_id_getter_proto_list: {
+            printGetByIdOp(exec, location, it, "get_by_id_getter_proto_list");
+            break;
+        }
+        case op_get_by_id_getter_chain: {
+            printGetByIdOp(exec, location, it, "get_by_id_getter_chain");
+            break;
+        }
+        case op_get_by_id_custom_self: {
+            printGetByIdOp(exec, location, it, "get_by_id_custom_self");
+            break;
+        }
+        case op_get_by_id_custom_self_list: {
+            printGetByIdOp(exec, location, it, "get_by_id_custom_self_list");
+            break;
+        }
+        case op_get_by_id_custom_proto: {
+            printGetByIdOp(exec, location, it, "get_by_id_custom_proto");
+            break;
+        }
+        case op_get_by_id_custom_proto_list: {
+            printGetByIdOp(exec, location, it, "get_by_id_custom_proto_list");
+            break;
+        }
+        case op_get_by_id_custom_chain: {
+            printGetByIdOp(exec, location, it, "get_by_id_custom_chain");
+            break;
+        }
         case op_get_by_id_generic: {
             printGetByIdOp(exec, location, it, "get_by_id_generic");
             break;
         case op_get_by_id_generic: {
             printGetByIdOp(exec, location, it, "get_by_id_generic");
             break;
@@ -797,14 +850,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
-            printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str());
+            printf("[%4d] put_getter\t %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
             break;
         }
         case op_put_setter: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             break;
         }
         case op_put_setter: {
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
-            printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str());
+            printf("[%4d] put_setter\t %s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
             break;
         }
         case op_method_check: {
             break;
         }
         case op_method_check: {
@@ -815,14 +868,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
-            printf("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), idName(id0, m_identifiers[id0]).c_str());
+            printf("[%4d] del_by_id\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), idName(id0, m_identifiers[id0]).data());
             break;
         }
         case op_get_by_val: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
             break;
         }
         case op_get_by_val: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
-            printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str());
+            printf("[%4d] get_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
             break;
         }
         case op_get_by_pname: {
             break;
         }
         case op_get_by_pname: {
@@ -832,28 +885,28 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int r3 = (++it)->u.operand;
             int r4 = (++it)->u.operand;
             int r5 = (++it)->u.operand;
             int r3 = (++it)->u.operand;
             int r4 = (++it)->u.operand;
             int r5 = (++it)->u.operand;
-            printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str(), registerName(exec, r4).c_str(), registerName(exec, r5).c_str());
+            printf("[%4d] get_by_pname\t %s, %s, %s, %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), registerName(exec, r4).data(), registerName(exec, r5).data());
             break;
         }
         case op_put_by_val: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
             break;
         }
         case op_put_by_val: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
-            printf("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str());
+            printf("[%4d] put_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
             break;
         }
         case op_del_by_val: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
             break;
         }
         case op_del_by_val: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r2 = (++it)->u.operand;
-            printf("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str());
+            printf("[%4d] del_by_val\t %s, %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data());
             break;
         }
         case op_put_by_index: {
             int r0 = (++it)->u.operand;
             unsigned n0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             break;
         }
         case op_put_by_index: {
             int r0 = (++it)->u.operand;
             unsigned n0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
-            printf("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).c_str(), n0, registerName(exec, r1).c_str());
+            printf("[%4d] put_by_index\t %s, %u, %s\n", location, registerName(exec, r0).data(), n0, registerName(exec, r1).data());
             break;
         }
         case op_jmp: {
             break;
         }
         case op_jmp: {
@@ -894,75 +947,82 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
             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(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
+            printf("[%4d] jneq_ptr\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
             break;
         }
         case op_jnless: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
             break;
         }
         case op_jnless: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
-            printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
+            printf("[%4d] jnless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
             break;
         }
         case op_jnlesseq: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
             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(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
+            printf("[%4d] jnlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
             break;
         }
         case op_loop_if_less: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
             break;
         }
         case op_loop_if_less: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
-            printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
+            printf("[%4d] loop_if_less\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
             break;
         }
         case op_jless: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
             break;
         }
         case op_jless: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
-            printf("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
+            printf("[%4d] jless\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
+            break;
+        }
+        case op_jlesseq: {
+            int r0 = (++it)->u.operand;
+            int r1 = (++it)->u.operand;
+            int offset = (++it)->u.operand;
+            printf("[%4d] jlesseq\t\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
             break;
         }
         case op_loop_if_lesseq: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
             break;
         }
         case op_loop_if_lesseq: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int offset = (++it)->u.operand;
-            printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), offset, location + offset);
+            printf("[%4d] loop_if_lesseq\t %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), offset, location + offset);
             break;
         }
         case op_switch_imm: {
             int tableIndex = (++it)->u.operand;
             int defaultTarget = (++it)->u.operand;
             int scrutineeRegister = (++it)->u.operand;
             break;
         }
         case op_switch_imm: {
             int tableIndex = (++it)->u.operand;
             int defaultTarget = (++it)->u.operand;
             int scrutineeRegister = (++it)->u.operand;
-            printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).c_str());
+            printf("[%4d] switch_imm\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
             break;
         }
         case op_switch_char: {
             int tableIndex = (++it)->u.operand;
             int defaultTarget = (++it)->u.operand;
             int scrutineeRegister = (++it)->u.operand;
             break;
         }
         case op_switch_char: {
             int tableIndex = (++it)->u.operand;
             int defaultTarget = (++it)->u.operand;
             int scrutineeRegister = (++it)->u.operand;
-            printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).c_str());
+            printf("[%4d] switch_char\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
             break;
         }
         case op_switch_string: {
             int tableIndex = (++it)->u.operand;
             int defaultTarget = (++it)->u.operand;
             int scrutineeRegister = (++it)->u.operand;
             break;
         }
         case op_switch_string: {
             int tableIndex = (++it)->u.operand;
             int defaultTarget = (++it)->u.operand;
             int scrutineeRegister = (++it)->u.operand;
-            printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).c_str());
+            printf("[%4d] switch_string\t %d, %d(->%d), %s\n", location, tableIndex, defaultTarget, location + defaultTarget, registerName(exec, scrutineeRegister).data());
             break;
         }
         case op_new_func: {
             int r0 = (++it)->u.operand;
             int f0 = (++it)->u.operand;
             break;
         }
         case op_new_func: {
             int r0 = (++it)->u.operand;
             int f0 = (++it)->u.operand;
-            printf("[%4d] new_func\t\t %s, f%d\n", location, registerName(exec, r0).c_str(), f0);
+            printf("[%4d] new_func\t\t %s, f%d\n", location, registerName(exec, r0).data(), f0);
             break;
         }
         case op_new_func_exp: {
             int r0 = (++it)->u.operand;
             int f0 = (++it)->u.operand;
             break;
         }
         case op_new_func_exp: {
             int r0 = (++it)->u.operand;
             int f0 = (++it)->u.operand;
-            printf("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).c_str(), f0);
+            printf("[%4d] new_func_exp\t %s, f%d\n", location, registerName(exec, r0).data(), f0);
             break;
         }
         case op_call: {
             break;
         }
         case op_call: {
@@ -970,7 +1030,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int func = (++it)->u.operand;
             int argCount = (++it)->u.operand;
             int registerOffset = (++it)->u.operand;
             int func = (++it)->u.operand;
             int argCount = (++it)->u.operand;
             int registerOffset = (++it)->u.operand;
-            printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset);
+            printf("[%4d] call\t\t %s, %s, %d, %d\n", location, registerName(exec, dst).data(), registerName(exec, func).data(), argCount, registerOffset);
             break;
         }
         case op_call_eval: {
             break;
         }
         case op_call_eval: {
@@ -978,7 +1038,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int func = (++it)->u.operand;
             int argCount = (++it)->u.operand;
             int registerOffset = (++it)->u.operand;
             int func = (++it)->u.operand;
             int argCount = (++it)->u.operand;
             int registerOffset = (++it)->u.operand;
-            printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset);
+            printf("[%4d] call_eval\t %s, %s, %d, %d\n", location, registerName(exec, dst).data(), registerName(exec, func).data(), argCount, registerOffset);
             break;
         }
         case op_call_varargs: {
             break;
         }
         case op_call_varargs: {
@@ -986,7 +1046,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int func = (++it)->u.operand;
             int argCount = (++it)->u.operand;
             int registerOffset = (++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(exec, dst).c_str(), registerName(exec, func).c_str(), registerName(exec, argCount).c_str(), registerOffset);
+            printf("[%4d] call_varargs\t %s, %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, func).data(), registerName(exec, argCount).data(), registerOffset);
             break;
         }
         case op_load_varargs: {
             break;
         }
         case op_load_varargs: {
@@ -995,7 +1055,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_tear_off_activation: {
             int r0 = (++it)->u.operand;
         }
         case op_tear_off_activation: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] tear_off_activation\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] tear_off_activation\t %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_tear_off_arguments: {
             break;
         }
         case op_tear_off_arguments: {
@@ -1004,7 +1064,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_ret: {
             int r0 = (++it)->u.operand;
         }
         case op_ret: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] ret\t\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] ret\t\t %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_construct: {
             break;
         }
         case op_construct: {
@@ -1014,26 +1074,26 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int registerOffset = (++it)->u.operand;
             int proto = (++it)->u.operand;
             int thisRegister = (++it)->u.operand;
             int registerOffset = (++it)->u.operand;
             int proto = (++it)->u.operand;
             int thisRegister = (++it)->u.operand;
-            printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(exec, dst).c_str(), registerName(exec, func).c_str(), argCount, registerOffset, registerName(exec, proto).c_str(), registerName(exec, thisRegister).c_str());
+            printf("[%4d] construct\t %s, %s, %d, %d, %s, %s\n", location, registerName(exec, dst).data(), registerName(exec, func).data(), argCount, registerOffset, registerName(exec, proto).data(), registerName(exec, thisRegister).data());
             break;
         }
         case op_construct_verify: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             break;
         }
         case op_construct_verify: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
-            printf("[%4d] construct_verify\t %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str());
+            printf("[%4d] construct_verify\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data());
             break;
         }
         case op_strcat: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int count = (++it)->u.operand;
             break;
         }
         case op_strcat: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int count = (++it)->u.operand;
-            printf("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), count);
+            printf("[%4d] strcat\t\t %s, %s, %d\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), count);
             break;
         }
         case op_to_primitive: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             break;
         }
         case op_to_primitive: {
             int r0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
-            printf("[%4d] to_primitive\t %s, %s\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str());
+            printf("[%4d] to_primitive\t %s, %s\n", location, registerName(exec, r0).data(), registerName(exec, r1).data());
             break;
         }
         case op_get_pnames: {
             break;
         }
         case op_get_pnames: {
@@ -1042,7 +1102,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int r2 = it[3].u.operand;
             int r3 = it[4].u.operand;
             int offset = it[5].u.operand;
             int r2 = it[3].u.operand;
             int r3 = it[4].u.operand;
             int offset = it[5].u.operand;
-            printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, r0).c_str(), registerName(exec, r1).c_str(), registerName(exec, r2).c_str(), registerName(exec, r3).c_str(), offset, location + offset);
+            printf("[%4d] get_pnames\t %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, r0).data(), registerName(exec, r1).data(), registerName(exec, r2).data(), registerName(exec, r3).data(), offset, location + offset);
             it += OPCODE_LENGTH(op_get_pnames) - 1;
             break;
         }
             it += OPCODE_LENGTH(op_get_pnames) - 1;
             break;
         }
@@ -1050,13 +1110,13 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int dest = it[1].u.operand;
             int iter = it[4].u.operand;
             int offset = it[5].u.operand;
             int dest = it[1].u.operand;
             int iter = it[4].u.operand;
             int offset = it[5].u.operand;
-            printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(exec, dest).c_str(), registerName(exec, iter).c_str(), offset, location + offset);
+            printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(exec, dest).data(), registerName(exec, iter).data(), offset, location + offset);
             it += OPCODE_LENGTH(op_next_pname) - 1;
             break;
         }
         case op_push_scope: {
             int r0 = (++it)->u.operand;
             it += OPCODE_LENGTH(op_next_pname) - 1;
             break;
         }
         case op_push_scope: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] push_scope\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] push_scope\t %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_pop_scope: {
             break;
         }
         case op_pop_scope: {
@@ -1067,7 +1127,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
             int r0 = (++it)->u.operand;
             int id0 = (++it)->u.operand;
             int r1 = (++it)->u.operand;
-            printf("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(exec, r0).c_str(), idName(id0, m_identifiers[id0]).c_str(), registerName(exec, r1).c_str());
+            printf("[%4d] push_new_scope \t%s, %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data(), registerName(exec, r1).data());
             break;
         }
         case op_jmp_scopes: {
             break;
         }
         case op_jmp_scopes: {
@@ -1078,30 +1138,30 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_catch: {
             int r0 = (++it)->u.operand;
         }
         case op_catch: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] catch\t\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] catch\t\t %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_throw: {
             int r0 = (++it)->u.operand;
             break;
         }
         case op_throw: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] throw\t\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] throw\t\t %s\n", location, registerName(exec, r0).data());
             break;
         }
         case op_new_error: {
             int r0 = (++it)->u.operand;
             int errorType = (++it)->u.operand;
             int k0 = (++it)->u.operand;
             break;
         }
         case op_new_error: {
             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(exec, r0).c_str(), errorType, constantName(exec, k0, getConstant(k0)).c_str());
+            printf("[%4d] new_error\t %s, %d, %s\n", location, registerName(exec, r0).data(), errorType, constantName(exec, k0, getConstant(k0)).data());
             break;
         }
         case op_jsr: {
             int retAddrDst = (++it)->u.operand;
             int offset = (++it)->u.operand;
             break;
         }
         case op_jsr: {
             int retAddrDst = (++it)->u.operand;
             int offset = (++it)->u.operand;
-            printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(exec, retAddrDst).c_str(), offset, location + offset);
+            printf("[%4d] jsr\t\t %s, %d(->%d)\n", location, registerName(exec, retAddrDst).data(), offset, location + offset);
             break;
         }
         case op_sret: {
             int retAddrSrc = (++it)->u.operand;
             break;
         }
         case op_sret: {
             int retAddrSrc = (++it)->u.operand;
-            printf("[%4d] sret\t\t %s\n", location, registerName(exec, retAddrSrc).c_str());
+            printf("[%4d] sret\t\t %s\n", location, registerName(exec, retAddrSrc).data());
             break;
         }
         case op_debug: {
             break;
         }
         case op_debug: {
@@ -1113,17 +1173,17 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
         }
         case op_profile_will_call: {
             int function = (++it)->u.operand;
         }
         case op_profile_will_call: {
             int function = (++it)->u.operand;
-            printf("[%4d] profile_will_call %s\n", location, registerName(exec, function).c_str());
+            printf("[%4d] profile_will_call %s\n", location, registerName(exec, function).data());
             break;
         }
         case op_profile_did_call: {
             int function = (++it)->u.operand;
             break;
         }
         case op_profile_did_call: {
             int function = (++it)->u.operand;
-            printf("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).c_str());
+            printf("[%4d] profile_did_call\t %s\n", location, registerName(exec, function).data());
             break;
         }
         case op_end: {
             int r0 = (++it)->u.operand;
             break;
         }
         case op_end: {
             int r0 = (++it)->u.operand;
-            printf("[%4d] end\t\t %s\n", location, registerName(exec, r0).c_str());
+            printf("[%4d] end\t\t %s\n", location, registerName(exec, r0).data());
             break;
         }
     }
             break;
         }
     }
@@ -1281,6 +1341,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassR
 #endif
     , m_needsFullScopeChain(ownerExecutable->needsActivation())
     , m_usesEval(ownerExecutable->usesEval())
 #endif
     , m_needsFullScopeChain(ownerExecutable->needsActivation())
     , m_usesEval(ownerExecutable->usesEval())
+    , m_usesArguments(false)
     , m_isNumericCompareFunction(false)
     , m_codeType(codeType)
     , m_source(sourceProvider)
     , m_isNumericCompareFunction(false)
     , m_codeType(codeType)
     , m_source(sourceProvider)
@@ -1297,13 +1358,14 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassR
 
 CodeBlock::~CodeBlock()
 {
 
 CodeBlock::~CodeBlock()
 {
-#if !ENABLE(JIT)
+#if ENABLE(INTERPRETER)
     for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
         derefStructures(&m_instructions[m_globalResolveInstructions[i]]);
 
     for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
         derefStructures(&m_instructions[m_propertyAccessInstructions[i]]);
     for (size_t size = m_globalResolveInstructions.size(), i = 0; i < size; ++i)
         derefStructures(&m_instructions[m_globalResolveInstructions[i]]);
 
     for (size_t size = m_propertyAccessInstructions.size(), i = 0; i < size; ++i)
         derefStructures(&m_instructions[m_propertyAccessInstructions[i]]);
-#else
+#endif
+#if ENABLE(JIT)
     for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) {
         if (m_globalResolveInfos[i].structure)
             m_globalResolveInfos[i].structure->deref();
     for (size_t size = m_globalResolveInfos.size(), i = 0; i < size; ++i) {
         if (m_globalResolveInfos[i].structure)
             m_globalResolveInfos[i].structure->deref();
@@ -1331,7 +1393,7 @@ CodeBlock::~CodeBlock()
     unlinkCallers();
 #endif
 
     unlinkCallers();
 #endif
 
-#endif // !ENABLE(JIT)
+#endif // ENABLE(JIT)
 
 #if DUMP_CODE_BLOCK_STATISTICS
     liveCodeBlockSet.remove(this);
 
 #if DUMP_CODE_BLOCK_STATISTICS
     liveCodeBlockSet.remove(this);
@@ -1355,16 +1417,16 @@ void CodeBlock::derefStructures(Instruction* vPC) const
 {
     Interpreter* interpreter = m_globalData->interpreter;
 
 {
     Interpreter* interpreter = m_globalData->interpreter;
 
-    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
+    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_self) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_self)) {
         vPC[4].u.structure->deref();
         return;
     }
         vPC[4].u.structure->deref();
         return;
     }
-    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
+    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_proto) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_proto)) {
         vPC[4].u.structure->deref();
         vPC[5].u.structure->deref();
         return;
     }
         vPC[4].u.structure->deref();
         vPC[5].u.structure->deref();
         return;
     }
-    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
+    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) {
         vPC[4].u.structure->deref();
         vPC[5].u.structureChain->deref();
         return;
         vPC[4].u.structure->deref();
         vPC[5].u.structureChain->deref();
         return;
@@ -1379,13 +1441,17 @@ void CodeBlock::derefStructures(Instruction* vPC) const
         vPC[4].u.structure->deref();
         return;
     }
         vPC[4].u.structure->deref();
         return;
     }
-    if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global)) {
+    if (vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global) || vPC[0].u.opcode == interpreter->getOpcode(op_resolve_global_dynamic)) {
         if(vPC[4].u.structure)
             vPC[4].u.structure->deref();
         return;
     }
     if ((vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto_list))
         if(vPC[4].u.structure)
             vPC[4].u.structure->deref();
         return;
     }
     if ((vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto_list))
-        || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self_list))) {
+        || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self_list))
+        || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_proto_list))
+        || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_self_list))
+        || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_proto_list))
+        || (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_self_list))) {
         PolymorphicAccessStructureList* polymorphicStructures = vPC[4].u.polymorphicStructures;
         polymorphicStructures->derefStructures(vPC[5].u.operand);
         delete polymorphicStructures;
         PolymorphicAccessStructureList* polymorphicStructures = vPC[4].u.polymorphicStructures;
         polymorphicStructures->derefStructures(vPC[5].u.operand);
         delete polymorphicStructures;
@@ -1400,16 +1466,16 @@ void CodeBlock::refStructures(Instruction* vPC) const
 {
     Interpreter* interpreter = m_globalData->interpreter;
 
 {
     Interpreter* interpreter = m_globalData->interpreter;
 
-    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self)) {
+    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_self) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_self)) {
         vPC[4].u.structure->ref();
         return;
     }
         vPC[4].u.structure->ref();
         return;
     }
-    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto)) {
+    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_proto) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_proto) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_proto)) {
         vPC[4].u.structure->ref();
         vPC[5].u.structure->ref();
         return;
     }
         vPC[4].u.structure->ref();
         vPC[5].u.structure->ref();
         return;
     }
-    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain)) {
+    if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_chain) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_custom_chain)) {
         vPC[4].u.structure->ref();
         vPC[5].u.structureChain->ref();
         return;
         vPC[4].u.structure->ref();
         vPC[5].u.structureChain->ref();
         return;
@@ -1595,7 +1661,7 @@ bool CodeBlock::functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int&
 }
 #endif
 
 }
 #endif
 
-#if !ENABLE(JIT)
+#if ENABLE(INTERPRETER)
 bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset)
 {
     if (m_globalResolveInstructions.isEmpty())
 bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset)
 {
     if (m_globalResolveInstructions.isEmpty())
@@ -1615,7 +1681,8 @@ bool CodeBlock::hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOff
         return false;
     return true;
 }
         return false;
     return true;
 }
-#else
+#endif
+#if ENABLE(JIT)
 bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
 {
     if (m_globalResolveInfos.isEmpty())
 bool CodeBlock::hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset)
 {
     if (m_globalResolveInfos.isEmpty())
@@ -1641,10 +1708,11 @@ void CodeBlock::shrinkToFit()
 {
     m_instructions.shrinkToFit();
 
 {
     m_instructions.shrinkToFit();
 
-#if !ENABLE(JIT)
+#if ENABLE(INTERPRETER)
     m_propertyAccessInstructions.shrinkToFit();
     m_globalResolveInstructions.shrinkToFit();
     m_propertyAccessInstructions.shrinkToFit();
     m_globalResolveInstructions.shrinkToFit();
-#else
+#endif
+#if ENABLE(JIT)
     m_structureStubInfos.shrinkToFit();
     m_globalResolveInfos.shrinkToFit();
     m_callLinkInfos.shrinkToFit();
     m_structureStubInfos.shrinkToFit();
     m_globalResolveInfos.shrinkToFit();
     m_callLinkInfos.shrinkToFit();
index eb874cc4c17b8a39a270f3c0d746e0641c72e819..63d9b8a16dafb7ab0e4e371df521a2d8ae375f56 100644 (file)
@@ -36,7 +36,6 @@
 #include "JSGlobalObject.h"
 #include "JumpTable.h"
 #include "Nodes.h"
 #include "JSGlobalObject.h"
 #include "JumpTable.h"
 #include "Nodes.h"
-#include "PtrAndFlags.h"
 #include "RegExp.h"
 #include "UString.h"
 #include <wtf/FastAllocBase.h>
 #include "RegExp.h"
 #include "UString.h"
 #include <wtf/FastAllocBase.h>
@@ -103,51 +102,63 @@ namespace JSC {
     struct CallLinkInfo {
         CallLinkInfo()
             : callee(0)
     struct CallLinkInfo {
         CallLinkInfo()
             : callee(0)
+            , position(0)
+            , hasSeenShouldRepatch(0)
         {
         }
         {
         }
-    
+
         unsigned bytecodeIndex;
         CodeLocationNearCall callReturnLocation;
         CodeLocationDataLabelPtr hotPathBegin;
         CodeLocationNearCall hotPathOther;
         unsigned bytecodeIndex;
         CodeLocationNearCall callReturnLocation;
         CodeLocationDataLabelPtr hotPathBegin;
         CodeLocationNearCall hotPathOther;
-        PtrAndFlags<CodeBlock, HasSeenShouldRepatch> ownerCodeBlock;
+        CodeBlock* ownerCodeBlock;
         CodeBlock* callee;
         CodeBlock* callee;
-        unsigned position;
+        unsigned position : 31;
+        unsigned hasSeenShouldRepatch : 1;
         
         void setUnlinked() { callee = 0; }
         bool isLinked() { return callee; }
 
         bool seenOnce()
         {
         
         void setUnlinked() { callee = 0; }
         bool isLinked() { return callee; }
 
         bool seenOnce()
         {
-            return ownerCodeBlock.isFlagSet(hasSeenShouldRepatch);
+            return hasSeenShouldRepatch;
         }
 
         void setSeen()
         {
         }
 
         void setSeen()
         {
-            ownerCodeBlock.setFlag(hasSeenShouldRepatch);
+            hasSeenShouldRepatch = true;
         }
     };
 
     struct MethodCallLinkInfo {
         MethodCallLinkInfo()
             : cachedStructure(0)
         }
     };
 
     struct MethodCallLinkInfo {
         MethodCallLinkInfo()
             : cachedStructure(0)
+            , cachedPrototypeStructure(0)
         {
         }
 
         bool seenOnce()
         {
         {
         }
 
         bool seenOnce()
         {
-            return cachedPrototypeStructure.isFlagSet(hasSeenShouldRepatch);
+            ASSERT(!cachedStructure);
+            return cachedPrototypeStructure;
         }
 
         void setSeen()
         {
         }
 
         void setSeen()
         {
-            cachedPrototypeStructure.setFlag(hasSeenShouldRepatch);
+            ASSERT(!cachedStructure && !cachedPrototypeStructure);
+            // We use the values of cachedStructure & cachedPrototypeStructure to indicate the
+            // current state.
+            //     - In the initial state, both are null.
+            //     - Once this transition has been taken once, cachedStructure is
+            //       null and cachedPrototypeStructure is set to a nun-null value.
+            //     - Once the call is linked both structures are set to non-null values.
+            cachedPrototypeStructure = (Structure*)1;
         }
 
         CodeLocationCall callReturnLocation;
         CodeLocationDataLabelPtr structureLabel;
         Structure* cachedStructure;
         }
 
         CodeLocationCall callReturnLocation;
         CodeLocationDataLabelPtr structureLabel;
         Structure* cachedStructure;
-        PtrAndFlags<Structure, HasSeenShouldRepatch> cachedPrototypeStructure;
+        Structure* cachedPrototypeStructure;
     };
 
     struct FunctionRegisterInfo {
     };
 
     struct FunctionRegisterInfo {
@@ -344,6 +355,12 @@ namespace JSC {
         
         bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex);
 #endif
         
         bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex);
 #endif
+#if ENABLE(INTERPRETER)
+        unsigned bytecodeOffset(CallFrame*, Instruction* returnAddress)
+        {
+            return static_cast<Instruction*>(returnAddress) - instructions().begin();
+        }
+#endif
 
         void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
         bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
 
         void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
         bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
@@ -385,11 +402,12 @@ namespace JSC {
         unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
         unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
 
         unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
         unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
 
-#if !ENABLE(JIT)
+#if ENABLE(INTERPRETER)
         void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { m_propertyAccessInstructions.append(propertyAccessInstruction); }
         void addGlobalResolveInstruction(unsigned globalResolveInstruction) { m_globalResolveInstructions.append(globalResolveInstruction); }
         bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
         void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { m_propertyAccessInstructions.append(propertyAccessInstruction); }
         void addGlobalResolveInstruction(unsigned globalResolveInstruction) { m_globalResolveInstructions.append(globalResolveInstruction); }
         bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
-#else
+#endif
+#if ENABLE(JIT)
         size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); }
         void addStructureStubInfo(const StructureStubInfo& stubInfo) { m_structureStubInfos.append(stubInfo); }
         StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; }
         size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); }
         void addStructureStubInfo(const StructureStubInfo& stubInfo) { m_structureStubInfos.append(stubInfo); }
         StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; }
@@ -519,10 +537,11 @@ namespace JSC {
         RefPtr<SourceProvider> m_source;
         unsigned m_sourceOffset;
 
         RefPtr<SourceProvider> m_source;
         unsigned m_sourceOffset;
 
-#if !ENABLE(JIT)
+#if ENABLE(INTERPRETER)
         Vector<unsigned> m_propertyAccessInstructions;
         Vector<unsigned> m_globalResolveInstructions;
         Vector<unsigned> m_propertyAccessInstructions;
         Vector<unsigned> m_globalResolveInstructions;
-#else
+#endif
+#if ENABLE(JIT)
         Vector<StructureStubInfo> m_structureStubInfos;
         Vector<GlobalResolveInfo> m_globalResolveInfos;
         Vector<CallLinkInfo> m_callLinkInfos;
         Vector<StructureStubInfo> m_structureStubInfos;
         Vector<GlobalResolveInfo> m_globalResolveInfos;
         Vector<CallLinkInfo> m_callLinkInfos;
index 05834fcbfe24e27e6f11148e16ac471234f2fe71..27c479d4e51c12fb3df93d671f5690a00bfaae39 100644 (file)
@@ -37,6 +37,7 @@
 #include "UString.h"
 #include <wtf/HashMap.h>
 #include <wtf/RefPtr.h>
 #include "UString.h"
 #include <wtf/HashMap.h>
 #include <wtf/RefPtr.h>
+#include <wtf/text/StringHash.h>
 
 namespace JSC {
 
 
 namespace JSC {
 
@@ -65,7 +66,7 @@ namespace JSC {
         bool isEmpty() const { return m_cacheMap.isEmpty(); }
 
     private:
         bool isEmpty() const { return m_cacheMap.isEmpty(); }
 
     private:
-        static const int maxCacheableSourceLength = 256;
+        static const unsigned maxCacheableSourceLength = 256;
         static const int maxCacheEntries = 64;
 
         typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalExecutable> > EvalCacheMap;
         static const int maxCacheEntries = 64;
 
         typedef HashMap<RefPtr<UString::Rep>, RefPtr<EvalExecutable> > EvalCacheMap;
index bcef7fb196a9c48b543315f3c0e6c0d4e78e0237..c6468a5580423b7267466abe46f1be4d6407d328 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "MacroAssembler.h"
 #include "Opcode.h"
 
 #include "MacroAssembler.h"
 #include "Opcode.h"
+#include "PropertySlot.h"
 #include "Structure.h"
 #include <wtf/VectorTraits.h>
 
 #include "Structure.h"
 #include <wtf/VectorTraits.h>
 
@@ -124,7 +125,7 @@ namespace JSC {
     struct Instruction {
         Instruction(Opcode opcode)
         {
     struct Instruction {
         Instruction(Opcode opcode)
         {
-#if !HAVE(COMPUTED_GOTO)
+#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
             // We have to initialize one of the pointer members to ensure that
             // the entire struct is initialized, when opcode is not a pointer.
             u.jsCell = 0;
             // We have to initialize one of the pointer members to ensure that
             // the entire struct is initialized, when opcode is not a pointer.
             u.jsCell = 0;
@@ -144,6 +145,7 @@ namespace JSC {
         Instruction(StructureChain* structureChain) { u.structureChain = structureChain; }
         Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
         Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; }
         Instruction(StructureChain* structureChain) { u.structureChain = structureChain; }
         Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
         Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; }
+        Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
 
         union {
             Opcode opcode;
 
         union {
             Opcode opcode;
@@ -152,6 +154,7 @@ namespace JSC {
             StructureChain* structureChain;
             JSCell* jsCell;
             PolymorphicAccessStructureList* polymorphicStructures;
             StructureChain* structureChain;
             JSCell* jsCell;
             PolymorphicAccessStructureList* polymorphicStructures;
+            PropertySlot::GetValueFunc getterFunc;
         } u;
     };
 
         } u;
     };
 
index 175c1b349c7f21d6bf55963135f61dbec7b8c642..ef7098b65695a61d6a5aa021dd50d72fd51e93d5 100644 (file)
@@ -30,6 +30,8 @@
 #include "config.h"
 #include "JumpTable.h"
 
 #include "config.h"
 #include "JumpTable.h"
 
+#include <wtf/text/StringHash.h>
+
 namespace JSC {
 
 int32_t SimpleJumpTable::offsetForValue(int32_t value, int32_t defaultOffset)
 namespace JSC {
 
 int32_t SimpleJumpTable::offsetForValue(int32_t value, int32_t defaultOffset)
index d9b2153dcad34154e67ca88c828ecf48418c0965..67f5e70790bbe1daa02bdd7b84c56a4bc97a8b84 100644 (file)
@@ -92,6 +92,7 @@ namespace JSC {
         macro(op_resolve, 3) \
         macro(op_resolve_skip, 4) \
         macro(op_resolve_global, 6) \
         macro(op_resolve, 3) \
         macro(op_resolve_skip, 4) \
         macro(op_resolve_global, 6) \
+        macro(op_resolve_global_dynamic, 7) \
         macro(op_get_scoped_var, 4) \
         macro(op_put_scoped_var, 4) \
         macro(op_get_global_var, 4) \
         macro(op_get_scoped_var, 4) \
         macro(op_put_scoped_var, 4) \
         macro(op_get_global_var, 4) \
@@ -104,13 +105,23 @@ namespace JSC {
         macro(op_get_by_id_proto, 8) \
         macro(op_get_by_id_proto_list, 8) \
         macro(op_get_by_id_chain, 8) \
         macro(op_get_by_id_proto, 8) \
         macro(op_get_by_id_proto_list, 8) \
         macro(op_get_by_id_chain, 8) \
+        macro(op_get_by_id_getter_self, 8) \
+        macro(op_get_by_id_getter_self_list, 8) \
+        macro(op_get_by_id_getter_proto, 8) \
+        macro(op_get_by_id_getter_proto_list, 8) \
+        macro(op_get_by_id_getter_chain, 8) \
+        macro(op_get_by_id_custom_self, 8) \
+        macro(op_get_by_id_custom_self_list, 8) \
+        macro(op_get_by_id_custom_proto, 8) \
+        macro(op_get_by_id_custom_proto_list, 8) \
+        macro(op_get_by_id_custom_chain, 8) \
         macro(op_get_by_id_generic, 8) \
         macro(op_get_array_length, 8) \
         macro(op_get_string_length, 8) \
         macro(op_get_by_id_generic, 8) \
         macro(op_get_array_length, 8) \
         macro(op_get_string_length, 8) \
-        macro(op_put_by_id, 8) \
-        macro(op_put_by_id_transition, 8) \
-        macro(op_put_by_id_replace, 8) \
-        macro(op_put_by_id_generic, 8) \
+        macro(op_put_by_id, 9) \
+        macro(op_put_by_id_transition, 9) \
+        macro(op_put_by_id_replace, 9) \
+        macro(op_put_by_id_generic, 9) \
         macro(op_del_by_id, 4) \
         macro(op_get_by_val, 4) \
         macro(op_get_by_pname, 7) \
         macro(op_del_by_id, 4) \
         macro(op_get_by_val, 4) \
         macro(op_get_by_pname, 7) \
@@ -129,6 +140,7 @@ namespace JSC {
         macro(op_jnless, 4) \
         macro(op_jnlesseq, 4) \
         macro(op_jless, 4) \
         macro(op_jnless, 4) \
         macro(op_jnlesseq, 4) \
         macro(op_jless, 4) \
+        macro(op_jlesseq, 4) \
         macro(op_jmp_scopes, 3) \
         macro(op_loop, 2) \
         macro(op_loop_if_true, 3) \
         macro(op_jmp_scopes, 3) \
         macro(op_loop, 2) \
         macro(op_loop_if_true, 3) \
@@ -195,7 +207,7 @@ namespace JSC {
         FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
     #undef VERIFY_OPCODE_ID
 
         FOR_EACH_OPCODE_ID(VERIFY_OPCODE_ID);
     #undef VERIFY_OPCODE_ID
 
-#if HAVE(COMPUTED_GOTO)
+#if ENABLE(COMPUTED_GOTO_INTERPRETER)
 #if COMPILER(RVCT)
     typedef void* Opcode;
 #else
 #if COMPILER(RVCT)
     typedef void* Opcode;
 #else
index 3f0babc5491cc1d72cb3cf54679ffc3d1a163d8b..7191e388ee61ee9f427ae8d4ba20e2730ef10f56 100644 (file)
@@ -43,7 +43,7 @@ namespace JSC {
 
 void SamplingFlags::sample()
 {
 
 void SamplingFlags::sample()
 {
-    uint32_t mask = 1 << 31;
+    uint32_t mask = static_cast<uint32_t>(1 << 31);
     unsigned index;
 
     for (index = 0; index < 32; ++index) {
     unsigned index;
 
     for (index = 0; index < 32; ++index) {
@@ -337,7 +337,7 @@ void SamplingTool::dump(ExecState* exec)
 
         if (blockPercent >= 1) {
             //Instruction* code = codeBlock->instructions().begin();
 
         if (blockPercent >= 1) {
             //Instruction* code = codeBlock->instructions().begin();
-            printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().UTF8String().c_str(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent);
+            printf("#%d: %s:%d: %d / %lld (%.3f%%)\n", i + 1, record->m_executable->sourceURL().ascii(), codeBlock->lineNumberForBytecodeOffset(exec, 0), record->m_sampleCount, m_sampleCount, blockPercent);
             if (i < 10) {
                 HashMap<unsigned,unsigned> lineCounts;
                 codeBlock->dump(exec);
             if (i < 10) {
                 HashMap<unsigned,unsigned> lineCounts;
                 codeBlock->dump(exec);
index b0a0877c15ba83b47b4dff470e37e487c99f3d1d..c4b3cab912b1b69897d4c886c45863048c50d999 100644 (file)
@@ -633,7 +633,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
             instructions().append(target->bind(begin, instructions().size()));
             return target;
         }
             instructions().append(target->bind(begin, instructions().size()));
             return target;
         }
-    } else if (m_lastOpcodeID == op_lesseq && !target->isForward()) {
+    } else if (m_lastOpcodeID == op_lesseq) {
         int dstIndex;
         int src1Index;
         int src2Index;
         int dstIndex;
         int src1Index;
         int src2Index;
@@ -644,7 +644,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
             rewindBinaryOp();
 
             size_t begin = instructions().size();
             rewindBinaryOp();
 
             size_t begin = instructions().size();
-            emitOpcode(op_loop_if_lesseq);
+            emitOpcode(target->isForward() ? op_jlesseq : op_loop_if_lesseq);
             instructions().append(src1Index);
             instructions().append(src2Index);
             instructions().append(target->bind(begin, instructions().size()));
             instructions().append(src1Index);
             instructions().append(src2Index);
             instructions().append(target->bind(begin, instructions().size()));
@@ -990,7 +990,7 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
     return constantID;
 }
 
     return constantID;
 }
 
-bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
+bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, bool& requiresDynamicChecks, JSObject*& globalObject)
 {
     // Cases where we cannot statically optimize the lookup.
     if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
 {
     // Cases where we cannot statically optimize the lookup.
     if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
@@ -1006,7 +1006,7 @@ bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& inde
     }
 
     size_t depth = 0;
     }
 
     size_t depth = 0;
-    
+    requiresDynamicChecks = false;
     ScopeChainIterator iter = m_scopeChain->begin();
     ScopeChainIterator end = m_scopeChain->end();
     for (; iter != end; ++iter, ++depth) {
     ScopeChainIterator iter = m_scopeChain->begin();
     ScopeChainIterator end = m_scopeChain->end();
     for (; iter != end; ++iter, ++depth) {
@@ -1031,10 +1031,11 @@ bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& inde
                 globalObject = currentVariableObject;
             return true;
         }
                 globalObject = currentVariableObject;
             return true;
         }
-        if (currentVariableObject->isDynamicScope())
+        bool scopeRequiresDynamicChecks = false;
+        if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks))
             break;
             break;
+        requiresDynamicChecks |= scopeRequiresDynamicChecks;
     }
     }
-
     // Can't locate the property but we're able to avoid a few lookups.
     stackDepth = depth;
     index = missingSymbolMarker();
     // Can't locate the property but we're able to avoid a few lookups.
     stackDepth = depth;
     index = missingSymbolMarker();
@@ -1059,7 +1060,8 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
-    if (!findScopedProperty(property, index, depth, false, globalObject) && !globalObject) {
+    bool requiresDynamicChecks = false;
+    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) && !globalObject) {
         // We can't optimise at all :-(
         emitOpcode(op_resolve);
         instructions().append(dst->index());
         // We can't optimise at all :-(
         emitOpcode(op_resolve);
         instructions().append(dst->index());
@@ -1077,7 +1079,7 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
 #endif
         }
 
 #endif
         }
 
-        if (index != missingSymbolMarker() && !forceGlobalResolve) {
+        if (index != missingSymbolMarker() && !forceGlobalResolve && !requiresDynamicChecks) {
             // Directly index the property lookup across multiple scopes.
             return emitGetScopedVar(dst, depth, index, globalObject);
         }
             // Directly index the property lookup across multiple scopes.
             return emitGetScopedVar(dst, depth, index, globalObject);
         }
@@ -1087,12 +1089,22 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
 #else
         m_codeBlock->addGlobalResolveInstruction(instructions().size());
 #endif
 #else
         m_codeBlock->addGlobalResolveInstruction(instructions().size());
 #endif
-        emitOpcode(op_resolve_global);
+        emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
         instructions().append(dst->index());
         instructions().append(globalObject);
         instructions().append(addConstant(property));
         instructions().append(0);
         instructions().append(0);
         instructions().append(dst->index());
         instructions().append(globalObject);
         instructions().append(addConstant(property));
         instructions().append(0);
         instructions().append(0);
+        if (requiresDynamicChecks)
+            instructions().append(depth);
+        return dst;
+    }
+
+    if (requiresDynamicChecks) {
+        // If we get here we have eval nested inside a |with| just give up
+        emitOpcode(op_resolve);
+        instructions().append(dst->index());
+        instructions().append(addConstant(property));
         return dst;
     }
 
         return dst;
     }
 
@@ -1148,8 +1160,9 @@ RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
-    findScopedProperty(property, index, depth, false, globalObject);
-    if (!globalObject) {
+    bool requiresDynamicChecks = false;
+    findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
+    if (!globalObject || requiresDynamicChecks) {
         // We can't optimise at all :-(
         emitOpcode(op_resolve_base);
         instructions().append(dst->index());
         // We can't optimise at all :-(
         emitOpcode(op_resolve_base);
         instructions().append(dst->index());
@@ -1166,7 +1179,8 @@ RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, Register
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
-    if (!findScopedProperty(property, index, depth, false, globalObject) || !globalObject) {
+    bool requiresDynamicChecks = false;
+    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) || !globalObject || requiresDynamicChecks) {
         // We can't optimise at all :-(
         emitOpcode(op_resolve_with_base);
         instructions().append(baseDst->index());
         // We can't optimise at all :-(
         emitOpcode(op_resolve_with_base);
         instructions().append(baseDst->index());
@@ -1198,12 +1212,14 @@ RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, Register
 #else
     m_codeBlock->addGlobalResolveInstruction(instructions().size());
 #endif
 #else
     m_codeBlock->addGlobalResolveInstruction(instructions().size());
 #endif
-    emitOpcode(op_resolve_global);
+    emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
     instructions().append(propDst->index());
     instructions().append(globalObject);
     instructions().append(addConstant(property));
     instructions().append(0);
     instructions().append(0);
     instructions().append(propDst->index());
     instructions().append(globalObject);
     instructions().append(addConstant(property));
     instructions().append(0);
     instructions().append(0);
+    if (requiresDynamicChecks)
+        instructions().append(depth);
     return baseDst;
 }
 
     return baseDst;
 }
 
@@ -1247,6 +1263,27 @@ RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& p
     instructions().append(0);
     instructions().append(0);
     instructions().append(0);
     instructions().append(0);
     instructions().append(0);
     instructions().append(0);
+    instructions().append(0);
+    return value;
+}
+
+RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
+{
+#if ENABLE(JIT)
+    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id));
+#else
+    m_codeBlock->addPropertyAccessInstruction(instructions().size());
+#endif
+    
+    emitOpcode(op_put_by_id);
+    instructions().append(base->index());
+    instructions().append(addConstant(property));
+    instructions().append(value->index());
+    instructions().append(0);
+    instructions().append(0);
+    instructions().append(0);
+    instructions().append(0);
+    instructions().append(property != m_globalData->propertyNames->underscoreProto);
     return value;
 }
 
     return value;
 }
 
@@ -1637,8 +1674,13 @@ void BytecodeGenerator::emitPopScope()
 
 void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
 {
 
 void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
 {
+#if ENABLE(DEBUG_WITH_BREAKPOINT)
+    if (debugHookID != DidReachBreakpoint)
+        return;
+#else
     if (!m_shouldEmitDebugHooks)
         return;
     if (!m_shouldEmitDebugHooks)
         return;
+#endif
     emitOpcode(op_debug);
     instructions().append(debugHookID);
     instructions().append(firstLine);
     emitOpcode(op_debug);
     instructions().append(debugHookID);
     instructions().append(firstLine);
@@ -1940,9 +1982,9 @@ static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t
     UNUSED_PARAM(max);
     ASSERT(node->isString());
     UString::Rep* clause = static_cast<StringNode*>(node)->value().ustring().rep();
     UNUSED_PARAM(max);
     ASSERT(node->isString());
     UString::Rep* clause = static_cast<StringNode*>(node)->value().ustring().rep();
-    ASSERT(clause->size() == 1);
+    ASSERT(clause->length() == 1);
     
     
-    int32_t key = clause->data()[0];
+    int32_t key = clause->characters()[0];
     ASSERT(key >= min);
     ASSERT(key <= max);
     return key - min;
     ASSERT(key >= min);
     ASSERT(key <= max);
     return key - min;
index 8b6a425194a3103dcbe81786d0efdc44b2273d2c..0bd81841fe81708c7be82efc629231797fbe0694 100644 (file)
@@ -106,7 +106,7 @@ namespace JSC {
         //
         // NB: depth does _not_ include the local scope.  eg. a depth of 0 refers
         // to the scope containing this codeblock.
         //
         // NB: depth does _not_ include the local scope.  eg. a depth of 0 refers
         // to the scope containing this codeblock.
-        bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting, JSObject*& globalObject);
+        bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting, bool& includesDynamicScopes, JSObject*& globalObject);
 
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
 
         // Returns the register storing "this"
         RegisterID* thisRegister() { return &m_thisRegister; }
@@ -301,6 +301,7 @@ namespace JSC {
 
         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
 
         RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
         RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
+        RegisterID* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value);
         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
         RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
         RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&);
         RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property);
         RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value);
@@ -380,8 +381,8 @@ namespace JSC {
         void emitOpcode(OpcodeID);
         void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
         void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
         void emitOpcode(OpcodeID);
         void retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index);
         void retrieveLastUnaryOp(int& dstIndex, int& srcIndex);
-        void rewindBinaryOp();
-        void rewindUnaryOp();
+        ALWAYS_INLINE void rewindBinaryOp();
+        ALWAYS_INLINE void rewindUnaryOp();
 
         PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
 
 
         PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
 
index b66c50d58b2c303f7fcc1473aa386170947dd762..2cb781ff158a470ef627870fe15801cb8a3ca51a 100644 (file)
@@ -39,6 +39,7 @@
 #include "Operations.h"
 #include "Parser.h"
 #include "PropertyNameArray.h"
 #include "Operations.h"
 #include "Parser.h"
 #include "PropertyNameArray.h"
+#include "RegExpCache.h"
 #include "RegExpObject.h"
 #include "SamplingTool.h"
 #include <wtf/Assertions.h>
 #include "RegExpObject.h"
 #include "SamplingTool.h"
 #include <wtf/Assertions.h>
@@ -76,8 +77,8 @@ namespace JSC {
 
 static void substitute(UString& string, const UString& substring)
 {
 
 static void substitute(UString& string, const UString& substring)
 {
-    int position = string.find("%s");
-    ASSERT(position != -1);
+    unsigned position = string.find("%s");
+    ASSERT(position != UString::NotFound);
     string = makeString(string.substr(0, position), substring, string.substr(position + 2));
 }
 
     string = makeString(string.substr(0, position), substring, string.substr(position + 2));
 }
 
@@ -144,7 +145,7 @@ RegisterID* StringNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
 
 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
 
 RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
 {
-    RefPtr<RegExp> regExp = RegExp::create(generator.globalData(), m_pattern.ustring(), m_flags.ustring());
+    RefPtr<RegExp> regExp = generator.globalData()->regExpCache()->lookupOrCreate(m_pattern.ustring(), m_flags.ustring());
     if (!regExp->isValid())
         return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage());
     if (dst == generator.ignoredResult())
     if (!regExp->isValid())
         return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage());
     if (dst == generator.ignoredResult())
@@ -265,7 +266,7 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe
         
         switch (p->m_node->m_type) {
             case PropertyNode::Constant: {
         
         switch (p->m_node->m_type) {
             case PropertyNode::Constant: {
-                generator.emitPutById(newObj.get(), p->m_node->name(), value);
+                generator.emitDirectPutById(newObj.get(), p->m_node->name(), value);
                 break;
             }
             case PropertyNode::Getter: {
                 break;
             }
             case PropertyNode::Getter: {
@@ -351,7 +352,8 @@ RegisterID* FunctionCallResolveNode::emitBytecode(BytecodeGenerator& generator,
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
-    if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
+    bool requiresDynamicChecks = false;
+    if (generator.findScopedProperty(m_ident, index, depth, false, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
         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, divot(), startOffset(), endOffset());
         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, divot(), startOffset(), endOffset());
@@ -524,7 +526,8 @@ RegisterID* PostfixResolveNode::emitBytecode(BytecodeGenerator& generator, Regis
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
-    if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
+    bool requiresDynamicChecks = false;
+    if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
         RegisterID* oldValue;
         if (dst == generator.ignoredResult()) {
         RefPtr<RegisterID> value = generator.emitGetScopedVar(generator.newTemporary(), depth, index, globalObject);
         RegisterID* oldValue;
         if (dst == generator.ignoredResult()) {
@@ -710,7 +713,8 @@ RegisterID* PrefixResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
-    if (generator.findScopedProperty(m_ident, index, depth, false, globalObject) && index != missingSymbolMarker()) {
+    bool requiresDynamicChecks = false;
+    if (generator.findScopedProperty(m_ident, index, depth, false, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         emitPreIncOrDec(generator, propDst.get(), m_operator);
         generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         emitPreIncOrDec(generator, propDst.get(), m_operator);
         generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
@@ -1132,7 +1136,8 @@ RegisterID* ReadModifyResolveNode::emitBytecode(BytecodeGenerator& generator, Re
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
-    if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
+    bool requiresDynamicChecks = false;
+    if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         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);
         RefPtr<RegisterID> src1 = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         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);
@@ -1161,7 +1166,8 @@ RegisterID* AssignResolveNode::emitBytecode(BytecodeGenerator& generator, Regist
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
     int index = 0;
     size_t depth = 0;
     JSObject* globalObject = 0;
-    if (generator.findScopedProperty(m_ident, index, depth, true, globalObject) && index != missingSymbolMarker()) {
+    bool requiresDynamicChecks = false;
+    if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
         if (dst == generator.ignoredResult())
             dst = 0;
         RegisterID* value = generator.emitNode(dst, m_right);
         if (dst == generator.ignoredResult())
             dst = 0;
         RegisterID* value = generator.emitNode(dst, m_right);
@@ -1699,7 +1705,7 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>&
             }
             const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
             if (singleCharacterSwitch &= value.size() == 1) {
             }
             const UString& value = static_cast<StringNode*>(clauseExpression)->value().ustring();
             if (singleCharacterSwitch &= value.size() == 1) {
-                int32_t intVal = value.rep()->data()[0];
+                int32_t intVal = value.rep()->characters()[0];
                 if (intVal < min_num)
                     min_num = intVal;
                 if (intVal > max_num)
                 if (intVal < min_num)
                     min_num = intVal;
                 if (intVal > max_num)
index d5fdfe9ddd63dc2f85376cdfe1f47096eff6d164..9810885d73490b8f503221e29af9c776c059e5d7 100644 (file)
--- a/config.h
+++ b/config.h
@@ -25,7 +25,7 @@
 
 #include <wtf/Platform.h>
 
 
 #include <wtf/Platform.h>
 
-#if OS(WINDOWS) && !defined(BUILDING_WX__) && !COMPILER(GCC)
+#if !PLATFORM(CHROMIUM) && OS(WINDOWS) && !defined(BUILDING_WX__) && !COMPILER(GCC)
 #if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
 #define JS_EXPORTDATA __declspec(dllexport)
 #else
 #if defined(BUILDING_JavaScriptCore) || defined(BUILDING_WTF)
 #define JS_EXPORTDATA __declspec(dllexport)
 #else
@@ -44,7 +44,7 @@
 #define max max
 #define min min
 
 #define max max
 #define min min
 
-#if !COMPILER(MSVC7) && !OS(WINCE)
+#if !COMPILER(MSVC7_OR_LOWER) && !OS(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
 // 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
 #include <wtf/DisallowCType.h>
 #endif
 
 #include <wtf/DisallowCType.h>
 #endif
 
+#if COMPILER(MSVC)
+#define SKIP_STATIC_CONSTRUCTORS_ON_MSVC 1
+#else
+#define SKIP_STATIC_CONSTRUCTORS_ON_GCC 1
+#endif
+
 #if PLATFORM(CHROMIUM)
 #if !defined(WTF_USE_V8)
 #define WTF_USE_V8 1
 #if PLATFORM(CHROMIUM)
 #if !defined(WTF_USE_V8)
 #define WTF_USE_V8 1
index 4184500ed4ccb6044f4a2ea8bde6ca79be4b7b63..6078f974f7b0e8ab9a5e65d0183569cd554c8ab1 100755 (executable)
@@ -247,27 +247,49 @@ sub output() {
         print "\nnamespace JSC {\n";
     }
     my $count = scalar @keys + 1;
         print "\nnamespace JSC {\n";
     }
     my $count = scalar @keys + 1;
+    print "#if ENABLE(JIT)\n";
+    print "#define THUNK_GENERATOR(generator) , generator\n";
+    print "#else\n";
+    print "#define THUNK_GENERATOR(generator)\n";
+    print "#endif\n";
     print "\nstatic const struct HashTableValue ${nameEntries}\[$count\] = {\n";
     my $i = 0;
     foreach my $key (@keys) {
         my $firstValue = "";
         my $secondValue = "";
     print "\nstatic const struct HashTableValue ${nameEntries}\[$count\] = {\n";
     my $i = 0;
     foreach my $key (@keys) {
         my $firstValue = "";
         my $secondValue = "";
+        my $castStr = "";
 
         if ($values[$i]{"type"} eq "Function") {
 
         if ($values[$i]{"type"} eq "Function") {
+            $castStr = "static_cast<NativeFunction>";
             $firstValue = $values[$i]{"function"};
             $secondValue = $values[$i]{"params"};
         } elsif ($values[$i]{"type"} eq "Property") {
             $firstValue = $values[$i]{"function"};
             $secondValue = $values[$i]{"params"};
         } elsif ($values[$i]{"type"} eq "Property") {
+            $castStr = "static_cast<PropertySlot::GetValueFunc>";
             $firstValue = $values[$i]{"get"};
             $secondValue = $values[$i]{"put"};
         } elsif ($values[$i]{"type"} eq "Lexer") {
             $firstValue = $values[$i]{"value"};
             $secondValue = "0";
         }
             $firstValue = $values[$i]{"get"};
             $secondValue = $values[$i]{"put"};
         } elsif ($values[$i]{"type"} eq "Lexer") {
             $firstValue = $values[$i]{"value"};
             $secondValue = "0";
         }
-        print "   { \"$key\", $attrs[$i], (intptr_t)$firstValue, (intptr_t)$secondValue },\n";
+        my $thunkGenerator = "0";
+        if ($key eq "charCodeAt") {
+            $thunkGenerator = "charCodeAtThunkGenerator";
+        }
+        if ($key eq "charAt") {
+            $thunkGenerator = "charAtThunkGenerator";
+        }
+        if ($key eq "sqrt") {
+            $thunkGenerator = "sqrtThunkGenerator";
+        }
+        if ($key eq "pow") {
+            $thunkGenerator = "powThunkGenerator";
+        }
+        print "   { \"$key\", $attrs[$i], (intptr_t)" . $castStr . "($firstValue), (intptr_t)$secondValue THUNK_GENERATOR($thunkGenerator) },\n";
         $i++;
     }
         $i++;
     }
-    print "   { 0, 0, 0, 0 }\n";
+    print "   { 0, 0, 0, 0 THUNK_GENERATOR(0) }\n";
     print "};\n\n";
     print "};\n\n";
+    print "#undef THUNK_GENERATOR\n";
     print "extern JSC_CONST_HASHTABLE HashTable $name =\n";
     print "    \{ $compactSize, $compactHashSizeMask, $nameEntries, 0 \};\n";
     print "} // namespace\n";
     print "extern JSC_CONST_HASHTABLE HashTable $name =\n";
     print "    \{ $compactSize, $compactHashSizeMask, $nameEntries, 0 \};\n";
     print "} // namespace\n";
diff --git a/create_jit_stubs b/create_jit_stubs
new file mode 100644 (file)
index 0000000..4d510ea
--- /dev/null
@@ -0,0 +1,69 @@
+#! /usr/bin/perl -w
+#
+# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+# Copyright (C) 2010 Patrick Gansterer <paroga@paroga.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.
+
+use strict;
+use File::Basename;
+use Getopt::Long;
+
+my $usage = basename($0) . " --prefix prefix [--offset offset] file";
+
+my $rtype_template = quotemeta("#rtype#");
+my $offset_template = quotemeta("#offset#");
+my $op_template = quotemeta("#op#");
+
+my $prefix;
+my $offset = 32;
+my $file;
+
+my $getOptionsResult = GetOptions(
+    'prefix=s' => \$prefix,
+    'offset=i' => \$offset
+);
+
+$file = $ARGV[0];
+
+die "$usage\n" unless ($prefix and $file);
+
+my $stub_template = "";
+my $stub = "";
+
+my $rtype = "";
+my $op = "";
+
+print STDERR "Creating JIT stubs for $file \n";
+open(IN, $file) or die "No such file $file";
+
+while ( $_ = <IN> ) {
+    if ( /^$prefix\((.*)\)/ ) {
+        $stub_template .= $1 . "\n";
+    }
+    if ( /^DEFINE_STUB_FUNCTION\((.*), (.*)\)/ ) {
+        $stub = $stub_template;
+        $rtype = quotemeta($1);
+        $op = quotemeta($2);
+        $stub =~ s/$offset_template/$offset/g;
+        $stub =~ s/$rtype_template/$rtype/g;
+        $stub =~ s/$op_template/$op/g;
+        $stub =~ s/\\\*/\*/g;
+        print $stub;
+    }
+}
+
+close(IN);
diff --git a/create_regex_tables b/create_regex_tables
new file mode 100644 (file)
index 0000000..b436eee
--- /dev/null
@@ -0,0 +1,112 @@
+# Copyright (C) 2010 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. 
+
+types = {
+    "wordchar": { "UseTable" : True, "data": ['_', ('0','9'), ('A', 'Z'), ('a','z')]},
+    "nonwordchar": { "UseTable" : True, "Inverse": "wordchar", "data": ['`', (0, ord('0') - 1), (ord('9') + 1, ord('A') - 1), (ord('Z') + 1, ord('_') - 1), (ord('z') + 1, 0xffff)]},
+    "newline": { "UseTable" : False, "data": ['\n', '\r', 0x2028, 0x2029]},
+    "spaces": { "UseTable" : True, "data": [' ', ('\t', '\r'), 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000, (0x2000, 0x200a)]},
+    "nonspaces": { "UseTable" : True, "Inverse": "spaces", "data": [(0, ord('\t') - 1), (ord('\r') + 1, ord(' ') - 1), (ord(' ') + 1, 0x009f), (0x00a1, 0x167f), (0x1681, 0x180d), (0x180f, 0x1fff), (0x200b, 0x2027), (0x202a, 0x202e), (0x2030, 0x205e), (0x2060, 0x2fff), (0x3001, 0xffff)]},
+    "digits": { "UseTable" : False, "data": [('0', '9')]},
+    "nondigits": { "UseTable" : False, "Inverse": "digits", "data": [(0, ord('0') - 1), (ord('9') + 1, 0xffff)] }
+}
+entriesPerLine = 50
+arrays = "";
+functions = "";
+
+for name, classes in types.items():
+    ranges = [];
+    size = 0;
+    for _class in classes["data"]:
+        if type(_class) == str:
+            ranges.append((ord(_class), ord(_class)))
+        elif type(_class) == int:
+            ranges.append((_class, _class))
+        else:
+            (min, max) = _class;
+            if type(min) == str:
+                min = ord(min)
+            if type(max) == str:
+                max = ord(max)
+            if max > 0x7f and min <= 0x7f:
+                ranges.append((min, 0x7f))
+                min = 0x80
+            ranges.append((min,max))
+    ranges.sort();
+    
+    if classes["UseTable"] and (not "Inverse" in classes):
+        array = ("static const char _%sData[65536] = {\n" % name);
+        i = 0
+        for (min,max) in ranges:
+            while i < min:
+                i = i + 1
+                array += ('0,')
+                if (i % entriesPerLine == 0) and (i != 0):
+                    array += ('\n')
+            while i <= max:
+                i = i + 1
+                if (i == 65536):
+                    array += ("1")
+                else:
+                    array += ('1,')
+                if (i % entriesPerLine == 0) and (i != 0):
+                    array += ('\n')
+        while i < 0xffff:
+            array += ("0,")
+            i = i + 1;
+            if (i % entriesPerLine == 0) and (i != 0):
+                array += ('\n')
+        if i == 0xffff:
+            array += ("0")
+        array += ("\n};\n\n");
+        arrays += array
+    
+    # Generate createFunction:
+    function = "";
+    function += ("CharacterClass* %sCreate()\n" % name)
+    function += ("{\n")
+    if classes["UseTable"]:
+        if "Inverse" in classes:
+            function += ("    CharacterClass* characterClass = new CharacterClass(CharacterClassTable::create(_%sData, true));\n" % (classes["Inverse"]))
+        else:
+            function += ("    CharacterClass* characterClass = new CharacterClass(CharacterClassTable::create(_%sData, false));\n" % (name))
+    else:
+        function += ("    CharacterClass* characterClass = new CharacterClass(0);\n")
+    for (min, max) in ranges:
+        if (min == max):
+            if (min > 127):
+                function += ("    characterClass->m_matchesUnicode.append(0x%04x);\n" % min)
+            else:
+                function += ("    characterClass->m_matches.append(0x%02x);\n" % min)
+            continue
+        if (min > 127) or (max > 127):
+            function += ("    characterClass->m_rangesUnicode.append(CharacterRange(0x%04x, 0x%04x));\n" % (min, max))
+        else:
+            function += ("    characterClass->m_ranges.append(CharacterRange(0x%02x, 0x%02x));\n" % (min, max))
+    function += ("    return characterClass;\n")
+    function += ("}\n\n")
+    functions += function
+
+print(arrays)
+print(functions)
+
diff --git a/create_rvct_stubs b/create_rvct_stubs
deleted file mode 100644 (file)
index 0c49c4f..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#! /usr/bin/perl -w
-#
-# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
-#
-# 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.
-
-use strict;
-
-my $file = $ARGV[0];
-shift;
-
-my $stub_template = "";
-my $stub = "";
-
-my $rtype = "";
-my $op = "";
-
-my $rtype_template = quotemeta("#rtype#");
-my $op_template = quotemeta("#op#");
-
-print STDERR "Creating RVCT stubs for $file \n";
-open(IN, $file) or die "No such file $file";
-
-while ( $_ = <IN> ) {
-    if ( /^RVCT\((.*)\)/ ) {
-        $stub_template .= $1 . "\n";
-    }
-    if ( /^DEFINE_STUB_FUNCTION\((.*), (.*)\)/ ) {
-        $stub = $stub_template;
-        $rtype = quotemeta($1);
-        $op = quotemeta($2);
-        $stub =~ s/$rtype_template/$rtype/g;
-        $stub =~ s/$op_template/$op/g;
-        $stub =~ s/\\\*/\*/g;
-        print $stub;
-    }
-}
-
-close(IN);
index 1d2e4fb62bda317b6e7f36e02b42102946ef118b..cbcbd21a96e8e2d3e1226b3e7122aa1b1973d81c 100644 (file)
@@ -94,7 +94,7 @@ void Debugger::recompileAllJSFunctions(JSGlobalData* globalData)
     // JavaScript in the inspector.
     SourceProviderMap::const_iterator end = sourceProviders.end();
     for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter)
     // JavaScript in the inspector.
     SourceProviderMap::const_iterator end = sourceProviders.end();
     for (SourceProviderMap::const_iterator iter = sourceProviders.begin(); iter != end; ++iter)
-        sourceParsed(iter->second, SourceCode(iter->first), -1, 0);
+        sourceParsed(iter->second, SourceCode(iter->first), -1, UString());
 }
 
 JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
 }
 
 JSValue evaluateInGlobalCallFrame(const UString& script, JSValue& exception, JSGlobalObject* globalObject)
index a3299d432a0afc79949c82f122be221802b7ef1f..a734b1d0e413db8c151ccefc745e920af9c6e630 100644 (file)
@@ -53,14 +53,14 @@ const UString* DebuggerCallFrame::functionName() const
 UString DebuggerCallFrame::calculatedFunctionName() const
 {
     if (!m_callFrame->codeBlock())
 UString DebuggerCallFrame::calculatedFunctionName() const
 {
     if (!m_callFrame->codeBlock())
-        return 0;
+        return UString();
 
     if (!m_callFrame->callee())
         return UString();
 
     JSFunction* function = asFunction(m_callFrame->callee());
     if (!function)
 
     if (!m_callFrame->callee())
         return UString();
 
     JSFunction* function = asFunction(m_callFrame->callee());
     if (!function)
-        return 0;
+        return UString();
     return function->calculatedDisplayName(m_callFrame);
 }
 
     return function->calculatedDisplayName(m_callFrame);
 }
 
index e3ea689165a8f5704a1cd74062932e65afc82283..fff6ea707a398df27b61b0f758f071505bd26479 100644 (file)
@@ -108,7 +108,12 @@ namespace JSC  {
 
         CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
         Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); }
 
         CallFrame* callerFrame() const { return this[RegisterFile::CallerFrame].callFrame(); }
         Arguments* optionalCalleeArguments() const { return this[RegisterFile::OptionalCalleeArguments].arguments(); }
-        Instruction* returnPC() const { return this[RegisterFile::ReturnPC].vPC(); }
+#if ENABLE(JIT)
+        ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[RegisterFile::ReturnPC].vPC()); }
+#endif
+#if ENABLE(INTERPRETER)
+        Instruction* returnVPC() const { return this[RegisterFile::ReturnPC].vPC(); }
+#endif
 
         void setCalleeArguments(JSValue arguments) { static_cast<Register*>(this)[RegisterFile::OptionalCalleeArguments] = arguments; }
         void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
 
         void setCalleeArguments(JSValue arguments) { static_cast<Register*>(this)[RegisterFile::OptionalCalleeArguments] = arguments; }
         void setCallerFrame(CallFrame* callerFrame) { static_cast<Register*>(this)[RegisterFile::CallerFrame] = callerFrame; }
index 56ee7ea9c5f522925fe95949f5ebb08649038028..9821c510be84a8dd792d3d4a01252e7ab8a10e43 100644 (file)
@@ -40,6 +40,7 @@
 #include "DebuggerCallFrame.h"
 #include "EvalCodeCache.h"
 #include "ExceptionHelpers.h"
 #include "DebuggerCallFrame.h"
 #include "EvalCodeCache.h"
 #include "ExceptionHelpers.h"
+#include "GetterSetter.h"
 #include "GlobalEvalFunction.h"
 #include "JSActivation.h"
 #include "JSArray.h"
 #include "GlobalEvalFunction.h"
 #include "JSActivation.h"
 #include "JSArray.h"
 #include "JIT.h"
 #endif
 
 #include "JIT.h"
 #endif
 
+#define WTF_USE_GCC_COMPUTED_GOTO_WORKAROUND (ENABLE(COMPUTED_GOTO_INTERPRETER) && !defined(__llvm__))
+
 using namespace std;
 
 namespace JSC {
 using namespace std;
 
 namespace JSC {
-
-static ALWAYS_INLINE unsigned bytecodeOffsetForPC(CallFrame* callFrame, CodeBlock* codeBlock, void* pc)
-{
+    
 #if ENABLE(JIT)
 #if ENABLE(JIT)
-    return codeBlock->getBytecodeIndex(callFrame, ReturnAddressPtr(pc));
-#else
-    UNUSED_PARAM(callFrame);
-    return static_cast<Instruction*>(pc) - codeBlock->instructions().begin();
+    static ALWAYS_INLINE unsigned bytecodeOffsetForPC(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr pc)
+    {
+        return codeBlock->getBytecodeIndex(callFrame, ReturnAddressPtr(pc));
+    }
+#endif
+#if ENABLE(INTERPRETER)
+    static ALWAYS_INLINE unsigned bytecodeOffsetForPC(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* pc)
+    {
+        UNUSED_PARAM(callFrame);
+        return pc - codeBlock->instructions().begin();
+    }
 #endif
 #endif
-}
 
 // Returns the depth of the scope chain within a given call frame.
 static int depth(CodeBlock* codeBlock, ScopeChain& sc)
 
 // Returns the depth of the scope chain within a given call frame.
 static int depth(CodeBlock* codeBlock, ScopeChain& sc)
@@ -88,7 +95,12 @@ static int depth(CodeBlock* codeBlock, ScopeChain& sc)
     return sc.localDepth();
 }
 
     return sc.localDepth();
 }
 
-#if USE(INTERPRETER)
+#if ENABLE(INTERPRETER) 
+static NEVER_INLINE JSValue concatenateStrings(ExecState* exec, Register* strings, unsigned count)
+{
+    return jsString(exec, strings, count);
+}
+
 NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
     int dst = vPC[1].u.operand;
 NEVER_INLINE bool Interpreter::resolve(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
 {
     int dst = vPC[1].u.operand;
@@ -169,7 +181,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
     PropertySlot slot(globalObject);
     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
         JSValue result = slot.getValue(callFrame, ident);
     PropertySlot slot(globalObject);
     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
         JSValue result = slot.getValue(callFrame, ident);
-        if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
+        if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
             if (vPC[4].u.structure)
                 vPC[4].u.structure->deref();
             globalObject->structure()->ref();
             if (vPC[4].u.structure)
                 vPC[4].u.structure->deref();
             globalObject->structure()->ref();
@@ -190,6 +202,76 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
     return false;
 }
 
     return false;
 }
 
+NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instruction* vPC, JSValue& exceptionValue)
+{
+    int dst = vPC[1].u.operand;
+    JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(vPC[2].u.jsCell);
+    ASSERT(globalObject->isGlobalObject());
+    int property = vPC[3].u.operand;
+    Structure* structure = vPC[4].u.structure;
+    int offset = vPC[5].u.operand;
+    CodeBlock* codeBlock = callFrame->codeBlock();
+    int skip = vPC[6].u.operand + codeBlock->needsFullScopeChain();
+    
+    ScopeChainNode* scopeChain = callFrame->scopeChain();
+    ScopeChainIterator iter = scopeChain->begin();
+    ScopeChainIterator end = scopeChain->end();
+    ASSERT(iter != end);
+    while (skip--) {
+        JSObject* o = *iter;
+        if (o->hasCustomProperties()) {
+            Identifier& ident = codeBlock->identifier(property);
+            do {
+                PropertySlot slot(o);
+                if (o->getPropertySlot(callFrame, ident, slot)) {
+                    JSValue result = slot.getValue(callFrame, ident);
+                    exceptionValue = callFrame->globalData().exception;
+                    if (exceptionValue)
+                        return false;
+                    callFrame->r(dst) = JSValue(result);
+                    return true;
+                }
+                if (iter == end)
+                    break;
+                o = *iter;
+                ++iter;
+            } while (true);
+            exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
+            return false;
+        }
+        ++iter;
+    }
+    
+    if (structure == globalObject->structure()) {
+        callFrame->r(dst) = JSValue(globalObject->getDirectOffset(offset));
+        return true;
+    }
+
+    Identifier& ident = codeBlock->identifier(property);
+    PropertySlot slot(globalObject);
+    if (globalObject->getPropertySlot(callFrame, ident, slot)) {
+        JSValue result = slot.getValue(callFrame, ident);
+        if (slot.isCacheableValue() && !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->r(dst) = JSValue(result);
+            return true;
+        }
+        
+        exceptionValue = callFrame->globalData().exception;
+        if (exceptionValue)
+            return false;
+        callFrame->r(dst) = JSValue(result);
+        return true;
+    }
+    
+    exceptionValue = createUndefinedVariableError(callFrame, ident, vPC - codeBlock->instructions().begin(), codeBlock);
+    return false;
+}
+
 NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
 {
     int dst = vPC[1].u.operand;
 NEVER_INLINE void Interpreter::resolveBase(CallFrame* callFrame, Instruction* vPC)
 {
     int dst = vPC[1].u.operand;
@@ -233,7 +315,7 @@ NEVER_INLINE bool Interpreter::resolveBaseAndProperty(CallFrame* callFrame, Inst
     return false;
 }
 
     return false;
 }
 
-#endif // USE(INTERPRETER)
+#endif // ENABLE(INTERPRETER)
 
 ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc)
 {
 
 ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc)
 {
@@ -272,7 +354,7 @@ ALWAYS_INLINE CallFrame* Interpreter::slideRegisterWindowForCall(CodeBlock* newC
     return CallFrame::create(r);
 }
 
     return CallFrame::create(r);
 }
 
-#if USE(INTERPRETER)
+#if ENABLE(INTERPRETER)
 static NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, CodeBlock* codeBlock, const Instruction* vPC, JSValue value, JSValue& exceptionData)
 {
     if (value.isObject())
 static NEVER_INLINE bool isInvalidParamForIn(CallFrame* callFrame, CodeBlock* codeBlock, const Instruction* vPC, JSValue value, JSValue& exceptionData)
 {
     if (value.isObject())
@@ -301,6 +383,8 @@ NEVER_INLINE JSValue Interpreter::callEval(CallFrame* callFrame, RegisterFile* r
         return program;
 
     UString programSource = asString(program)->value(callFrame);
         return program;
 
     UString programSource = asString(program)->value(callFrame);
+    if (callFrame->hadException())
+        return JSValue();
 
     LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON);
     if (JSValue parsedObject = preparser.tryLiteralParse())
 
     LiteralParser preparser(callFrame, programSource, LiteralParser::NonStrictJSON);
     if (JSValue parsedObject = preparser.tryLiteralParse())
@@ -321,12 +405,12 @@ Interpreter::Interpreter()
     : m_sampleEntryDepth(0)
     , m_reentryDepth(0)
 {
     : m_sampleEntryDepth(0)
     , m_reentryDepth(0)
 {
-#if HAVE(COMPUTED_GOTO)
+#if ENABLE(COMPUTED_GOTO_INTERPRETER)
     privateExecute(InitializeAndReturn, 0, 0, 0);
 
     for (int i = 0; i < numOpcodeIDs; ++i)
         m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
     privateExecute(InitializeAndReturn, 0, 0, 0);
 
     for (int i = 0; i < numOpcodeIDs; ++i)
         m_opcodeIDTable.add(m_opcodeTable[i], static_cast<OpcodeID>(i));
-#endif // HAVE(COMPUTED_GOTO)
+#endif // ENABLE(COMPUTED_GOTO_INTERPRETER)
 
 #if ENABLE(OPCODE_SAMPLING)
     enableSampler();
 
 #if ENABLE(OPCODE_SAMPLING)
     enableSampler();
@@ -436,7 +520,7 @@ void Interpreter::dumpRegisters(CallFrame* callFrame)
 
 bool Interpreter::isOpcode(Opcode opcode)
 {
 
 bool Interpreter::isOpcode(Opcode opcode)
 {
-#if HAVE(COMPUTED_GOTO)
+#if ENABLE(COMPUTED_GOTO_INTERPRETER)
     return opcode != HashTraits<Opcode>::emptyValue()
         && !HashTraits<Opcode>::isDeletedValue(opcode)
         && m_opcodeIDTable.contains(opcode);
     return opcode != HashTraits<Opcode>::emptyValue()
         && !HashTraits<Opcode>::isDeletedValue(opcode)
         && m_opcodeIDTable.contains(opcode);
@@ -478,13 +562,24 @@ NEVER_INLINE bool Interpreter::unwindCallFrame(CallFrame*& callFrame, JSValue ex
     if (oldCodeBlock->needsFullScopeChain())
         scopeChain->deref();
 
     if (oldCodeBlock->needsFullScopeChain())
         scopeChain->deref();
 
-    void* returnPC = callFrame->returnPC();
-    callFrame = callFrame->callerFrame();
-    if (callFrame->hasHostCallFrameFlag())
+    ExecState* callerFrame = callFrame->callerFrame();
+    if (callerFrame->hasHostCallFrameFlag())
         return false;
 
         return false;
 
-    codeBlock = callFrame->codeBlock();
-    bytecodeOffset = bytecodeOffsetForPC(callFrame, codeBlock, returnPC);
+    codeBlock = callerFrame->codeBlock();
+#if ENABLE(JIT)
+#if ENABLE(INTERPRETER)
+    if (callerFrame->globalData().canUseJIT())
+#endif
+        bytecodeOffset = bytecodeOffsetForPC(callerFrame, codeBlock, callFrame->returnPC());
+#if ENABLE(INTERPRETER)
+    else
+        bytecodeOffset = bytecodeOffsetForPC(callerFrame, codeBlock, callFrame->returnVPC());
+#endif
+#else
+    bytecodeOffset = codeBlock->bytecodeOffset(callerFrame, callFrame->returnVPC());
+#endif
+    callFrame = callerFrame;
     return true;
 }
 
     return true;
 }
 
@@ -521,8 +616,9 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
                 exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerExecutable()->sourceID()), ReadOnly | DontDelete);
                 exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceURL"), jsOwnedString(callFrame, codeBlock->ownerExecutable()->sourceURL()), ReadOnly | DontDelete);
             }
                 exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerExecutable()->sourceID()), ReadOnly | DontDelete);
                 exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceURL"), jsOwnedString(callFrame, codeBlock->ownerExecutable()->sourceURL()), ReadOnly | DontDelete);
             }
-            
-            if (exception->isWatchdogException()) {
+
+            ComplType exceptionType = exception->exceptionType();
+            if (exceptionType == Interrupted || exceptionType == Terminated) {
                 while (unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) {
                     // Don't need handler checks or anything, we just want to unroll all the JS callframes possible.
                 }
                 while (unwindCallFrame(callFrame, exceptionValue, bytecodeOffset, codeBlock)) {
                     // Don't need handler checks or anything, we just want to unroll all the JS callframes possible.
                 }
@@ -541,15 +637,24 @@ NEVER_INLINE HandlerInfo* Interpreter::throwException(CallFrame*& callFrame, JSV
     // the profiler manually that the call instruction has returned, since
     // we'll never reach the relevant op_profile_did_call.
     if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
     // the profiler manually that the call instruction has returned, since
     // we'll never reach the relevant op_profile_did_call.
     if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
-#if !ENABLE(JIT)
-        if (isCallBytecode(codeBlock->instructions()[bytecodeOffset].u.opcode))
-            profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 2].u.operand).jsValue());
-        else if (codeBlock->instructions().size() > (bytecodeOffset + 8) && codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct))
-            profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 10].u.operand).jsValue());
-#else
-        int functionRegisterIndex;
-        if (codeBlock->functionRegisterForBytecodeOffset(bytecodeOffset, functionRegisterIndex))
-            profiler->didExecute(callFrame, callFrame->r(functionRegisterIndex).jsValue());
+#if ENABLE(INTERPRETER)
+        if (!callFrame->globalData().canUseJIT()) {
+            // FIXME: Why 8? - work out what this magic value is, replace the constant with something more helpful.
+            if (isCallBytecode(codeBlock->instructions()[bytecodeOffset].u.opcode))
+                profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 1].u.operand).jsValue());
+            else if (codeBlock->instructions().size() > (bytecodeOffset + 8) && codeBlock->instructions()[bytecodeOffset + 8].u.opcode == getOpcode(op_construct))
+                profiler->didExecute(callFrame, callFrame->r(codeBlock->instructions()[bytecodeOffset + 9].u.operand).jsValue());
+        }
+#if ENABLE(JIT)
+        else
+#endif
+#endif
+#if ENABLE(JIT)
+        {
+            int functionRegisterIndex;
+            if (codeBlock->functionRegisterForBytecodeOffset(bytecodeOffset, functionRegisterIndex))
+                profiler->didExecute(callFrame, callFrame->r(functionRegisterIndex).jsValue());
+        }
 #endif
     }
 
 #endif
     }
 
@@ -578,8 +683,8 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
 {
     ASSERT(!scopeChain->globalData->exception);
 
 {
     ASSERT(!scopeChain->globalData->exception);
 
-    if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
-        if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
+    if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
+        if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
             *exception = createStackOverflowError(callFrame);
             return jsNull();
         }
             *exception = createStackOverflowError(callFrame);
             return jsNull();
         }
@@ -615,12 +720,20 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
     {
         SamplingTool::CallRecord callRecord(m_sampler.get());
 
     {
         SamplingTool::CallRecord callRecord(m_sampler.get());
 
-        m_reentryDepth++;
+        m_reentryDepth++;  
 #if ENABLE(JIT)
 #if ENABLE(JIT)
-        result = program->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
-#else
-        result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
+#if ENABLE(INTERPRETER)
+        if (callFrame->globalData().canUseJIT())
+#endif
+            result = program->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+#if ENABLE(INTERPRETER)
+        else
+#endif
 #endif
 #endif
+#if ENABLE(INTERPRETER)
+            result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
+#endif
+
         m_reentryDepth--;
     }
 
         m_reentryDepth--;
     }
 
@@ -639,8 +752,8 @@ JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame*
 {
     ASSERT(!scopeChain->globalData->exception);
 
 {
     ASSERT(!scopeChain->globalData->exception);
 
-    if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
-        if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
+    if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
+        if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
             *exception = createStackOverflowError(callFrame);
             return jsNull();
         }
             *exception = createStackOverflowError(callFrame);
             return jsNull();
         }
@@ -683,8 +796,15 @@ JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame*
 
         m_reentryDepth++;
 #if ENABLE(JIT)
 
         m_reentryDepth++;
 #if ENABLE(JIT)
-        result = functionExecutable->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
-#else
+#if ENABLE(INTERPRETER)
+        if (scopeChain->globalData->canUseJIT())
+#endif
+            result = functionExecutable->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+#if ENABLE(INTERPRETER)
+        else
+#endif
+#endif
+#if ENABLE(INTERPRETER)
         result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
         m_reentryDepth--;
         result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
         m_reentryDepth--;
@@ -701,8 +821,8 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
 {
     ASSERT(!scopeChain->globalData->exception);
     
 {
     ASSERT(!scopeChain->globalData->exception);
     
-    if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
-        if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
+    if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
+        if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
             *exception = createStackOverflowError(callFrame);
             return CallFrameClosure();
         }
             *exception = createStackOverflowError(callFrame);
             return CallFrameClosure();
         }
@@ -729,11 +849,13 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
         return CallFrameClosure();
     }
     // a 0 codeBlock indicates a built-in caller
         return CallFrameClosure();
     }
     // a 0 codeBlock indicates a built-in caller
-    newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function);
+    newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function);  
 #if ENABLE(JIT)
 #if ENABLE(JIT)
-    FunctionExecutable->jitCode(newCallFrame, scopeChain);
+#if ENABLE(INTERPRETER)
+    if (callFrame->globalData().canUseJIT())
+#endif
+        FunctionExecutable->jitCode(newCallFrame, scopeChain);
 #endif
 #endif
-
     CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
     return result;
 }
     CallFrameClosure result = { callFrame, newCallFrame, function, FunctionExecutable, scopeChain->globalData, oldEnd, scopeChain, codeBlock->m_numParameters, argc };
     return result;
 }
@@ -749,11 +871,18 @@ JSValue Interpreter::execute(CallFrameClosure& closure, JSValue* exception)
     {
         SamplingTool::CallRecord callRecord(m_sampler.get());
         
     {
         SamplingTool::CallRecord callRecord(m_sampler.get());
         
-        m_reentryDepth++;
+        m_reentryDepth++;  
 #if ENABLE(JIT)
 #if ENABLE(JIT)
-        result = closure.functionExecutable->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception);
-#else
-        result = privateExecute(Normal, &m_registerFile, closure.newCallFrame, exception);
+#if ENABLE(INTERPRETER)
+        if (closure.newCallFrame->globalData().canUseJIT())
+#endif
+            result = closure.functionExecutable->generatedJITCode().execute(&m_registerFile, closure.newCallFrame, closure.globalData, exception);
+#if ENABLE(INTERPRETER)
+        else
+#endif
+#endif
+#if ENABLE(INTERPRETER)
+            result = privateExecute(Normal, &m_registerFile, closure.newCallFrame, exception);
 #endif
         m_reentryDepth--;
     }
 #endif
         m_reentryDepth--;
     }
@@ -777,8 +906,8 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
 {
     ASSERT(!scopeChain->globalData->exception);
 
 {
     ASSERT(!scopeChain->globalData->exception);
 
-    if (m_reentryDepth >= MaxSecondaryThreadReentryDepth) {
-        if (!isMainThread() || m_reentryDepth >= MaxMainThreadReentryDepth) {
+    if (m_reentryDepth >= MaxSmallThreadReentryDepth) {
+        if (m_reentryDepth >= callFrame->globalData().maxReentryDepth) {
             *exception = createStackOverflowError(callFrame);
             return jsNull();
         }
             *exception = createStackOverflowError(callFrame);
             return jsNull();
         }
@@ -797,11 +926,12 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
         }
     }
 
         }
     }
 
-    { // Scope for BatchedTransitionOptimizer
-
+    unsigned numVariables = codeBlock->numVariables();
+    int numFunctions = codeBlock->numberOfFunctionDecls();
+    if (numVariables || numFunctions) {
+        // Scope for BatchedTransitionOptimizer
         BatchedTransitionOptimizer optimizer(variableObject);
 
         BatchedTransitionOptimizer optimizer(variableObject);
 
-        unsigned numVariables = codeBlock->numVariables();
         for (unsigned i = 0; i < numVariables; ++i) {
             const Identifier& ident = codeBlock->variable(i);
             if (!variableObject->hasProperty(callFrame, ident)) {
         for (unsigned i = 0; i < numVariables; ++i) {
             const Identifier& ident = codeBlock->variable(i);
             if (!variableObject->hasProperty(callFrame, ident)) {
@@ -810,13 +940,11 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
             }
         }
 
             }
         }
 
-        int numFunctions = codeBlock->numberOfFunctionDecls();
         for (int i = 0; i < numFunctions; ++i) {
             FunctionExecutable* function = codeBlock->functionDecl(i);
             PutPropertySlot slot;
             variableObject->put(callFrame, function->name(), function->make(callFrame, scopeChain), slot);
         }
         for (int i = 0; i < numFunctions; ++i) {
             FunctionExecutable* function = codeBlock->functionDecl(i);
             PutPropertySlot slot;
             variableObject->put(callFrame, function->name(), function->make(callFrame, scopeChain), slot);
         }
-
     }
 
     Register* oldEnd = m_registerFile.end();
     }
 
     Register* oldEnd = m_registerFile.end();
@@ -844,10 +972,18 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
         SamplingTool::CallRecord callRecord(m_sampler.get());
 
         m_reentryDepth++;
         SamplingTool::CallRecord callRecord(m_sampler.get());
 
         m_reentryDepth++;
+        
 #if ENABLE(JIT)
 #if ENABLE(JIT)
-        result = eval->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
-#else
-        result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
+#if ENABLE(INTERPRETER)
+        if (callFrame->globalData().canUseJIT())
+#endif
+            result = eval->jitCode(newCallFrame, scopeChain).execute(&m_registerFile, newCallFrame, scopeChain->globalData, exception);
+#if ENABLE(INTERPRETER)
+        else
+#endif
+#endif
+#if ENABLE(INTERPRETER)
+            result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
 #endif
         m_reentryDepth--;
     }
 #endif
         m_reentryDepth--;
     }
@@ -887,7 +1023,7 @@ NEVER_INLINE void Interpreter::debug(CallFrame* callFrame, DebugHookID debugHook
     }
 }
     
     }
 }
     
-#if USE(INTERPRETER)
+#if ENABLE(INTERPRETER)
 NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
 {
     int dst = vPC[1].u.operand;
 NEVER_INLINE ScopeChainNode* Interpreter::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
 {
     int dst = vPC[1].u.operand;
@@ -1029,8 +1165,20 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
     // Cache hit: Specialize instruction and ref Structures.
 
     if (slot.slotBase() == baseValue) {
     // Cache hit: Specialize instruction and ref Structures.
 
     if (slot.slotBase() == baseValue) {
-        vPC[0] = getOpcode(op_get_by_id_self);
-        vPC[5] = slot.cachedOffset();
+        switch (slot.cachedPropertyType()) {
+        case PropertySlot::Getter:
+            vPC[0] = getOpcode(op_get_by_id_getter_self);
+            vPC[5] = slot.cachedOffset();
+            break;
+        case PropertySlot::Custom:
+            vPC[0] = getOpcode(op_get_by_id_custom_self);
+            vPC[5] = slot.customGetter();
+            break;
+        default:
+            vPC[0] = getOpcode(op_get_by_id_self);
+            vPC[5] = slot.cachedOffset();
+            break;
+        }
 
         codeBlock->refStructures(vPC);
         return;
 
         codeBlock->refStructures(vPC);
         return;
@@ -1055,10 +1203,22 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
         }
 
         ASSERT(!baseObject->structure()->isUncacheableDictionary());
         }
 
         ASSERT(!baseObject->structure()->isUncacheableDictionary());
-
-        vPC[0] = getOpcode(op_get_by_id_proto);
+        
+        switch (slot.cachedPropertyType()) {
+        case PropertySlot::Getter:
+            vPC[0] = getOpcode(op_get_by_id_getter_proto);
+            vPC[6] = offset;
+            break;
+        case PropertySlot::Custom:
+            vPC[0] = getOpcode(op_get_by_id_custom_proto);
+            vPC[6] = slot.customGetter();
+            break;
+        default:
+            vPC[0] = getOpcode(op_get_by_id_proto);
+            vPC[6] = offset;
+            break;
+        }
         vPC[5] = baseObject->structure();
         vPC[5] = baseObject->structure();
-        vPC[6] = offset;
 
         codeBlock->refStructures(vPC);
         return;
 
         codeBlock->refStructures(vPC);
         return;
@@ -1071,11 +1231,24 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
         return;
     }
 
         return;
     }
 
-    vPC[0] = getOpcode(op_get_by_id_chain);
+    
+    switch (slot.cachedPropertyType()) {
+    case PropertySlot::Getter:
+        vPC[0] = getOpcode(op_get_by_id_getter_chain);
+        vPC[7] = offset;
+        break;
+    case PropertySlot::Custom:
+        vPC[0] = getOpcode(op_get_by_id_custom_chain);
+        vPC[7] = slot.customGetter();
+        break;
+    default:
+        vPC[0] = getOpcode(op_get_by_id_chain);
+        vPC[7] = offset;
+        break;
+    }
     vPC[4] = structure;
     vPC[5] = structure->prototypeChain(callFrame);
     vPC[6] = count;
     vPC[4] = structure;
     vPC[5] = structure->prototypeChain(callFrame);
     vPC[6] = count;
-    vPC[7] = offset;
     codeBlock->refStructures(vPC);
 }
 
     codeBlock->refStructures(vPC);
 }
 
@@ -1086,28 +1259,32 @@ NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock* codeBlock, Instruction*
     vPC[4] = 0;
 }
 
     vPC[4] = 0;
 }
 
-#endif // USE(INTERPRETER)
+#endif // ENABLE(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 (UNLIKELY(flag == InitializeAndReturn)) {
 
 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 (UNLIKELY(flag == InitializeAndReturn)) {
-        #if HAVE(COMPUTED_GOTO)
+        #if ENABLE(COMPUTED_GOTO_INTERPRETER)
             #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
             #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)
+        #endif // ENABLE(COMPUTED_GOTO_INTERPRETER)
         return JSValue();
     }
         return JSValue();
     }
-
+    
 #if ENABLE(JIT)
 #if ENABLE(JIT)
+#if ENABLE(INTERPRETER)
     // Mixing Interpreter + JIT is not supported.
     // Mixing Interpreter + JIT is not supported.
-    ASSERT_NOT_REACHED();
+    if (callFrame->globalData().canUseJIT())
+#endif
+        ASSERT_NOT_REACHED();
 #endif
 #endif
-#if !USE(INTERPRETER)
+
+#if !ENABLE(INTERPRETER)
     UNUSED_PARAM(registerFile);
     UNUSED_PARAM(callFrame);
     UNUSED_PARAM(exception);
     UNUSED_PARAM(registerFile);
     UNUSED_PARAM(callFrame);
     UNUSED_PARAM(exception);
@@ -1136,7 +1313,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
 #define CHECK_FOR_TIMEOUT() \
     if (!--tickCount) { \
 
 #define CHECK_FOR_TIMEOUT() \
     if (!--tickCount) { \
-        if (globalData->timeoutChecker.didTimeOut(callFrame)) { \
+        if (globalData->terminator.shouldTerminate() || globalData->timeoutChecker.didTimeOut(callFrame)) { \
             exceptionValue = jsNull(); \
             goto vm_throw; \
         } \
             exceptionValue = jsNull(); \
             goto vm_throw; \
         } \
@@ -1149,7 +1326,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
     #define SAMPLE(codeBlock, vPC)
 #endif
 
     #define SAMPLE(codeBlock, vPC)
 #endif
 
-#if HAVE(COMPUTED_GOTO)
+#if ENABLE(COMPUTED_GOTO_INTERPRETER)
     #define NEXT_INSTRUCTION() SAMPLE(callFrame->codeBlock(), vPC); goto *vPC->u.opcode
 #if ENABLE(OPCODE_STATS)
     #define DEFINE_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode);
     #define NEXT_INSTRUCTION() SAMPLE(callFrame->codeBlock(), vPC); goto *vPC->u.opcode
 #if ENABLE(OPCODE_STATS)
     #define DEFINE_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode);
@@ -1314,7 +1491,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         int dst = vPC[1].u.operand;
         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
         int dst = vPC[1].u.operand;
         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
-        callFrame->r(dst) = jsBoolean(JSValue::strictEqual(callFrame, src1, src2));
+        bool result = JSValue::strictEqual(callFrame, src1, src2);
+        CHECK_FOR_EXCEPTION();
+        callFrame->r(dst) = jsBoolean(result);
 
         vPC += OPCODE_LENGTH(op_stricteq);
         NEXT_INSTRUCTION();
 
         vPC += OPCODE_LENGTH(op_stricteq);
         NEXT_INSTRUCTION();
@@ -1329,7 +1508,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         int dst = vPC[1].u.operand;
         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
         int dst = vPC[1].u.operand;
         JSValue src1 = callFrame->r(vPC[2].u.operand).jsValue();
         JSValue src2 = callFrame->r(vPC[3].u.operand).jsValue();
-        callFrame->r(dst) = jsBoolean(!JSValue::strictEqual(callFrame, src1, src2));
+        bool result = !JSValue::strictEqual(callFrame, src1, src2);
+        CHECK_FOR_EXCEPTION();
+        callFrame->r(dst) = jsBoolean(result);
 
         vPC += OPCODE_LENGTH(op_nstricteq);
         NEXT_INSTRUCTION();
 
         vPC += OPCODE_LENGTH(op_nstricteq);
         NEXT_INSTRUCTION();
@@ -1482,7 +1663,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         */
         int dst = vPC[1].u.operand;
         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
         */
         int dst = vPC[1].u.operand;
         JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
-        if (src.isInt32() && src.asInt32())
+        if (src.isInt32() && (src.asInt32() & 0x7fffffff)) // non-zero and no overflow
             callFrame->r(dst) = jsNumber(callFrame, -src.asInt32());
         else {
             JSValue result = jsNumber(callFrame, -src.toNumber(callFrame));
             callFrame->r(dst) = jsNumber(callFrame, -src.asInt32());
         else {
             JSValue result = jsNumber(callFrame, -src.toNumber(callFrame));
@@ -1964,6 +2145,24 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         
         NEXT_INSTRUCTION();
     }
         
         NEXT_INSTRUCTION();
     }
+    DEFINE_OPCODE(op_resolve_global_dynamic) {
+        /* resolve_skip dst(r) globalObject(c) property(id) structure(sID) offset(n), depth(n)
+         
+         Performs a dynamic property lookup for the given property, on the provided
+         global object.  If structure matches the Structure of the global then perform
+         a fast lookup using the case offset, otherwise fall back to a full resolve and
+         cache the new structure and offset.
+         
+         This walks through n levels of the scope chain to verify that none of those levels
+         in the scope chain include dynamically added properties.
+         */
+        if (UNLIKELY(!resolveGlobalDynamic(callFrame, vPC, exceptionValue)))
+            goto vm_throw;
+        
+        vPC += OPCODE_LENGTH(op_resolve_global_dynamic);
+        
+        NEXT_INSTRUCTION();
+    }
     DEFINE_OPCODE(op_get_global_var) {
         /* get_global_var dst(r) globalObject(c) index(n)
 
     DEFINE_OPCODE(op_get_global_var) {
         /* get_global_var dst(r) globalObject(c) index(n)
 
@@ -1991,7 +2190,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
         vPC += OPCODE_LENGTH(op_put_global_var);
         NEXT_INSTRUCTION();
         scope->registerAt(index) = JSValue(callFrame->r(value).jsValue());
         vPC += OPCODE_LENGTH(op_put_global_var);
         NEXT_INSTRUCTION();
-    }            
+    }
     DEFINE_OPCODE(op_get_scoped_var) {
         /* get_scoped_var dst(r) index(n) skip(n)
 
     DEFINE_OPCODE(op_get_scoped_var) {
         /* get_scoped_var dst(r) index(n) skip(n)
 
@@ -2010,7 +2209,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             ++iter;
             ASSERT(iter != end);
         }
             ++iter;
             ASSERT(iter != end);
         }
-
         ASSERT((*iter)->isVariableObject());
         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
         callFrame->r(dst) = scope->registerAt(index);
         ASSERT((*iter)->isVariableObject());
         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
         callFrame->r(dst) = scope->registerAt(index);
@@ -2161,6 +2359,93 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         uncacheGetByID(callFrame->codeBlock(), vPC);
         NEXT_INSTRUCTION();
     }
         uncacheGetByID(callFrame->codeBlock(), vPC);
         NEXT_INSTRUCTION();
     }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    goto *(&&skip_id_getter_proto);
+#endif
+    DEFINE_OPCODE(op_get_by_id_getter_proto) {
+        /* op_get_by_id_getter_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
+         
+         Cached property access: Attempts to get a cached getter property from the
+         value base's prototype. If the cache misses, op_get_by_id_getter_proto
+         reverts to op_get_by_id.
+         */
+        int base = vPC[2].u.operand;
+        JSValue baseValue = callFrame->r(base).jsValue();
+        
+        if (LIKELY(baseValue.isCell())) {
+            JSCell* baseCell = asCell(baseValue);
+            Structure* structure = vPC[4].u.structure;
+            
+            if (LIKELY(baseCell->structure() == structure)) {
+                ASSERT(structure->prototypeForLookup(callFrame).isObject());
+                JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
+                Structure* prototypeStructure = vPC[5].u.structure;
+                
+                if (LIKELY(protoObject->structure() == prototypeStructure)) {
+                    int dst = vPC[1].u.operand;
+                    int offset = vPC[6].u.operand;
+                    if (GetterSetter* getterSetter = asGetterSetter(protoObject->getDirectOffset(offset).asCell())) {
+                        JSObject* getter = getterSetter->getter();
+                        CallData callData;
+                        CallType callType = getter->getCallData(callData);
+                        JSValue result = call(callFrame, getter, callType, callData, asObject(baseCell), ArgList());
+                        CHECK_FOR_EXCEPTION();
+                        callFrame->r(dst) = result;
+                    } else
+                        callFrame->r(dst) = jsUndefined();
+                    vPC += OPCODE_LENGTH(op_get_by_id_getter_proto);
+                    NEXT_INSTRUCTION();
+                }
+            }
+        }
+        uncacheGetByID(callFrame->codeBlock(), vPC);
+        NEXT_INSTRUCTION();
+    }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    skip_id_getter_proto:
+#endif
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    goto *(&&skip_id_custom_proto);
+#endif
+    DEFINE_OPCODE(op_get_by_id_custom_proto) {
+        /* op_get_by_id_custom_proto dst(r) base(r) property(id) structure(sID) prototypeStructure(sID) offset(n) nop(n)
+         
+         Cached property access: Attempts to use a cached named property getter
+         from the value base's prototype. If the cache misses, op_get_by_id_custom_proto
+         reverts to op_get_by_id.
+         */
+        int base = vPC[2].u.operand;
+        JSValue baseValue = callFrame->r(base).jsValue();
+        
+        if (LIKELY(baseValue.isCell())) {
+            JSCell* baseCell = asCell(baseValue);
+            Structure* structure = vPC[4].u.structure;
+            
+            if (LIKELY(baseCell->structure() == structure)) {
+                ASSERT(structure->prototypeForLookup(callFrame).isObject());
+                JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
+                Structure* prototypeStructure = vPC[5].u.structure;
+                
+                if (LIKELY(protoObject->structure() == prototypeStructure)) {
+                    int dst = vPC[1].u.operand;
+                    int property = vPC[3].u.operand;
+                    Identifier& ident = callFrame->codeBlock()->identifier(property);
+                    
+                    PropertySlot::GetValueFunc getter = vPC[6].u.getterFunc;
+                    JSValue result = getter(callFrame, protoObject, ident);
+                    CHECK_FOR_EXCEPTION();
+                    callFrame->r(dst) = result;
+                    vPC += OPCODE_LENGTH(op_get_by_id_custom_proto);
+                    NEXT_INSTRUCTION();
+                }
+            }
+        }
+        uncacheGetByID(callFrame->codeBlock(), vPC);
+        NEXT_INSTRUCTION();
+    }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    skip_id_custom_proto:
+#endif
     DEFINE_OPCODE(op_get_by_id_self_list) {
         // Polymorphic self access caching currently only supported when JITting.
         ASSERT_NOT_REACHED();
     DEFINE_OPCODE(op_get_by_id_self_list) {
         // Polymorphic self access caching currently only supported when JITting.
         ASSERT_NOT_REACHED();
@@ -2175,6 +2460,34 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         vPC += OPCODE_LENGTH(op_get_by_id_proto_list);
         NEXT_INSTRUCTION();
     }
         vPC += OPCODE_LENGTH(op_get_by_id_proto_list);
         NEXT_INSTRUCTION();
     }
+    DEFINE_OPCODE(op_get_by_id_getter_self_list) {
+        // Polymorphic self access caching currently only supported when JITting.
+        ASSERT_NOT_REACHED();
+        // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)!
+        vPC += OPCODE_LENGTH(op_get_by_id_self_list);
+        NEXT_INSTRUCTION();
+    }
+    DEFINE_OPCODE(op_get_by_id_getter_proto_list) {
+        // Polymorphic prototype access caching currently only supported when JITting.
+        ASSERT_NOT_REACHED();
+        // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)!
+        vPC += OPCODE_LENGTH(op_get_by_id_proto_list);
+        NEXT_INSTRUCTION();
+    }
+    DEFINE_OPCODE(op_get_by_id_custom_self_list) {
+        // Polymorphic self access caching currently only supported when JITting.
+        ASSERT_NOT_REACHED();
+        // This case of the switch must not be empty, else (op_get_by_id_self_list == op_get_by_id_chain)!
+        vPC += OPCODE_LENGTH(op_get_by_id_custom_self_list);
+        NEXT_INSTRUCTION();
+    }
+    DEFINE_OPCODE(op_get_by_id_custom_proto_list) {
+        // Polymorphic prototype access caching currently only supported when JITting.
+        ASSERT_NOT_REACHED();
+        // This case of the switch must not be empty, else (op_get_by_id_proto_list == op_get_by_id_chain)!
+        vPC += OPCODE_LENGTH(op_get_by_id_proto_list);
+        NEXT_INSTRUCTION();
+    }
     DEFINE_OPCODE(op_get_by_id_chain) {
         /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
 
     DEFINE_OPCODE(op_get_by_id_chain) {
         /* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
 
@@ -2221,6 +2534,86 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         uncacheGetByID(callFrame->codeBlock(), vPC);
         NEXT_INSTRUCTION();
     }
         uncacheGetByID(callFrame->codeBlock(), vPC);
         NEXT_INSTRUCTION();
     }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    goto *(&&skip_id_getter_self);
+#endif
+    DEFINE_OPCODE(op_get_by_id_getter_self) {
+        /* op_get_by_id_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
+         
+         Cached property access: Attempts to get a cached property from the
+         value base. If the cache misses, op_get_by_id_getter_self reverts to
+         op_get_by_id.
+         */
+        int base = vPC[2].u.operand;
+        JSValue baseValue = callFrame->r(base).jsValue();
+        
+        if (LIKELY(baseValue.isCell())) {
+            JSCell* baseCell = asCell(baseValue);
+            Structure* structure = vPC[4].u.structure;
+            
+            if (LIKELY(baseCell->structure() == structure)) {
+                ASSERT(baseCell->isObject());
+                JSObject* baseObject = asObject(baseCell);
+                int dst = vPC[1].u.operand;
+                int offset = vPC[5].u.operand;
+
+                if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
+                    JSObject* getter = getterSetter->getter();
+                    CallData callData;
+                    CallType callType = getter->getCallData(callData);
+                    JSValue result = call(callFrame, getter, callType, callData, baseObject, ArgList());
+                    CHECK_FOR_EXCEPTION();
+                    callFrame->r(dst) = result;
+                } else
+                    callFrame->r(dst) = jsUndefined();
+
+                vPC += OPCODE_LENGTH(op_get_by_id_getter_self);
+                NEXT_INSTRUCTION();
+            }
+        }
+        uncacheGetByID(callFrame->codeBlock(), vPC);
+        NEXT_INSTRUCTION();
+    }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    skip_id_getter_self:
+#endif
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    goto *(&&skip_id_custom_self);
+#endif
+    DEFINE_OPCODE(op_get_by_id_custom_self) {
+        /* op_get_by_id_custom_self dst(r) base(r) property(id) structure(sID) offset(n) nop(n) nop(n)
+         
+         Cached property access: Attempts to use a cached named property getter
+         from the value base. If the cache misses, op_get_by_id_custom_self reverts to
+         op_get_by_id.
+         */
+        int base = vPC[2].u.operand;
+        JSValue baseValue = callFrame->r(base).jsValue();
+        
+        if (LIKELY(baseValue.isCell())) {
+            JSCell* baseCell = asCell(baseValue);
+            Structure* structure = vPC[4].u.structure;
+            
+            if (LIKELY(baseCell->structure() == structure)) {
+                ASSERT(baseCell->isObject());
+                int dst = vPC[1].u.operand;
+                int property = vPC[3].u.operand;
+                Identifier& ident = callFrame->codeBlock()->identifier(property);
+
+                PropertySlot::GetValueFunc getter = vPC[5].u.getterFunc;
+                JSValue result = getter(callFrame, baseValue, ident);
+                CHECK_FOR_EXCEPTION();
+                callFrame->r(dst) = result;
+                vPC += OPCODE_LENGTH(op_get_by_id_custom_self);
+                NEXT_INSTRUCTION();
+            }
+        }
+        uncacheGetByID(callFrame->codeBlock(), vPC);
+        NEXT_INSTRUCTION();
+    }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+skip_id_custom_self:
+#endif
     DEFINE_OPCODE(op_get_by_id_generic) {
         /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
 
     DEFINE_OPCODE(op_get_by_id_generic) {
         /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
 
@@ -2241,6 +2634,113 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         vPC += OPCODE_LENGTH(op_get_by_id_generic);
         NEXT_INSTRUCTION();
     }
         vPC += OPCODE_LENGTH(op_get_by_id_generic);
         NEXT_INSTRUCTION();
     }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    goto *(&&skip_id_getter_chain);
+#endif
+    DEFINE_OPCODE(op_get_by_id_getter_chain) {
+        /* op_get_by_id_getter_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
+         
+         Cached property access: Attempts to get a cached property from the
+         value base's prototype chain. If the cache misses, op_get_by_id_getter_chain
+         reverts to op_get_by_id.
+         */
+        int base = vPC[2].u.operand;
+        JSValue baseValue = callFrame->r(base).jsValue();
+        
+        if (LIKELY(baseValue.isCell())) {
+            JSCell* baseCell = asCell(baseValue);
+            Structure* structure = vPC[4].u.structure;
+            
+            if (LIKELY(baseCell->structure() == structure)) {
+                RefPtr<Structure>* it = vPC[5].u.structureChain->head();
+                size_t count = vPC[6].u.operand;
+                RefPtr<Structure>* end = it + count;
+                
+                while (true) {
+                    JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
+                    
+                    if (UNLIKELY(baseObject->structure() != (*it).get()))
+                        break;
+                    
+                    if (++it == end) {
+                        int dst = vPC[1].u.operand;
+                        int offset = vPC[7].u.operand;
+                        if (GetterSetter* getterSetter = asGetterSetter(baseObject->getDirectOffset(offset).asCell())) {
+                            JSObject* getter = getterSetter->getter();
+                            CallData callData;
+                            CallType callType = getter->getCallData(callData);
+                            JSValue result = call(callFrame, getter, callType, callData, baseValue, ArgList());
+                            CHECK_FOR_EXCEPTION();
+                            callFrame->r(dst) = result;
+                        } else
+                            callFrame->r(dst) = jsUndefined();
+                        vPC += OPCODE_LENGTH(op_get_by_id_getter_chain);
+                        NEXT_INSTRUCTION();
+                    }
+                    
+                    // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
+                    baseCell = baseObject;
+                }
+            }
+        }
+        uncacheGetByID(callFrame->codeBlock(), vPC);
+        NEXT_INSTRUCTION();
+    }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    skip_id_getter_chain:
+#endif
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    goto *(&&skip_id_custom_chain);
+#endif
+    DEFINE_OPCODE(op_get_by_id_custom_chain) {
+        /* op_get_by_id_custom_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
+         
+         Cached property access: Attempts to use a cached named property getter on the
+         value base's prototype chain. If the cache misses, op_get_by_id_custom_chain
+         reverts to op_get_by_id.
+         */
+        int base = vPC[2].u.operand;
+        JSValue baseValue = callFrame->r(base).jsValue();
+        
+        if (LIKELY(baseValue.isCell())) {
+            JSCell* baseCell = asCell(baseValue);
+            Structure* structure = vPC[4].u.structure;
+            
+            if (LIKELY(baseCell->structure() == structure)) {
+                RefPtr<Structure>* it = vPC[5].u.structureChain->head();
+                size_t count = vPC[6].u.operand;
+                RefPtr<Structure>* end = it + count;
+                
+                while (true) {
+                    JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
+                    
+                    if (UNLIKELY(baseObject->structure() != (*it).get()))
+                        break;
+                    
+                    if (++it == end) {
+                        int dst = vPC[1].u.operand;
+                        int property = vPC[3].u.operand;
+                        Identifier& ident = callFrame->codeBlock()->identifier(property);
+                        
+                        PropertySlot::GetValueFunc getter = vPC[7].u.getterFunc;
+                        JSValue result = getter(callFrame, baseObject, ident);
+                        CHECK_FOR_EXCEPTION();
+                        callFrame->r(dst) = result;
+                        vPC += OPCODE_LENGTH(op_get_by_id_custom_chain);
+                        NEXT_INSTRUCTION();
+                    }
+                    
+                    // Update baseCell, so that next time around the loop we'll pick up the prototype's prototype.
+                    baseCell = baseObject;
+                }
+            }
+        }
+        uncacheGetByID(callFrame->codeBlock(), vPC);
+        NEXT_INSTRUCTION();
+    }
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+    skip_id_custom_chain:
+#endif
     DEFINE_OPCODE(op_get_array_length) {
         /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
 
     DEFINE_OPCODE(op_get_array_length) {
         /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
 
@@ -2282,24 +2782,32 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id) {
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id) {
-        /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n)
+        /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)
 
            Generic property access: Sets the property named by identifier
            property, belonging to register base, to register value.
 
            Unlike many opcodes, this one does not write any output to
            the register file.
 
            Generic property access: Sets the property named by identifier
            property, belonging to register base, to register value.
 
            Unlike many opcodes, this one does not write any output to
            the register file.
+           The "direct" flag should only be set this put_by_id is to initialize
+           an object literal.
         */
 
         int base = vPC[1].u.operand;
         int property = vPC[2].u.operand;
         int value = vPC[3].u.operand;
         */
 
         int base = vPC[1].u.operand;
         int property = vPC[2].u.operand;
         int value = vPC[3].u.operand;
+        int direct = vPC[8].u.operand;
 
         CodeBlock* codeBlock = callFrame->codeBlock();
         JSValue baseValue = callFrame->r(base).jsValue();
         Identifier& ident = codeBlock->identifier(property);
         PutPropertySlot slot;
 
         CodeBlock* codeBlock = callFrame->codeBlock();
         JSValue baseValue = callFrame->r(base).jsValue();
         Identifier& ident = codeBlock->identifier(property);
         PutPropertySlot slot;
-        baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
+        if (direct) {
+            baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot);
+            ASSERT(slot.base() == baseValue);
+        } else
+            baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
         CHECK_FOR_EXCEPTION();
 
         tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
         CHECK_FOR_EXCEPTION();
 
         tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
@@ -2308,7 +2816,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id_transition) {
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id_transition) {
-        /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n)
+        /* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
          
            Cached property access: Attempts to set a new property with a cached transition
            property named by identifier property, belonging to register base,
          
            Cached property access: Attempts to set a new property with a cached transition
            property named by identifier property, belonging to register base,
@@ -2329,19 +2837,21 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             if (LIKELY(baseCell->structure() == oldStructure)) {
                 ASSERT(baseCell->isObject());
                 JSObject* baseObject = asObject(baseCell);
             if (LIKELY(baseCell->structure() == oldStructure)) {
                 ASSERT(baseCell->isObject());
                 JSObject* baseObject = asObject(baseCell);
-
-                RefPtr<Structure>* it = vPC[6].u.structureChain->head();
-
-                JSValue proto = baseObject->structure()->prototypeForLookup(callFrame);
-                while (!proto.isNull()) {
-                    if (UNLIKELY(asObject(proto)->structure() != (*it).get())) {
-                        uncachePutByID(callFrame->codeBlock(), vPC);
-                        NEXT_INSTRUCTION();
+                int direct = vPC[8].u.operand;
+
+                if (!direct) {
+                    RefPtr<Structure>* it = vPC[6].u.structureChain->head();
+
+                    JSValue proto = baseObject->structure()->prototypeForLookup(callFrame);
+                    while (!proto.isNull()) {
+                        if (UNLIKELY(asObject(proto)->structure() != (*it).get())) {
+                            uncachePutByID(callFrame->codeBlock(), vPC);
+                            NEXT_INSTRUCTION();
+                        }
+                        ++it;
+                        proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
                     }
                     }
-                    ++it;
-                    proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
                 }
                 }
-
                 baseObject->transitionTo(newStructure);
 
                 int value = vPC[3].u.operand;
                 baseObject->transitionTo(newStructure);
 
                 int value = vPC[3].u.operand;
@@ -2358,7 +2868,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id_replace) {
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id_replace) {
-        /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n)
+        /* op_put_by_id_replace base(r) property(id) value(r) structure(sID) offset(n) nop(n) nop(n) direct(b)
 
            Cached property access: Attempts to set a pre-existing, cached
            property named by identifier property, belonging to register base,
 
            Cached property access: Attempts to set a pre-existing, cached
            property named by identifier property, belonging to register base,
@@ -2393,7 +2903,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id_generic) {
         NEXT_INSTRUCTION();
     }
     DEFINE_OPCODE(op_put_by_id_generic) {
-        /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n)
+        /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)
 
            Generic property access: Sets the property named by identifier
            property, belonging to register base, to register value.
 
            Generic property access: Sets the property named by identifier
            property, belonging to register base, to register value.
@@ -2404,11 +2914,16 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         int base = vPC[1].u.operand;
         int property = vPC[2].u.operand;
         int value = vPC[3].u.operand;
         int base = vPC[1].u.operand;
         int property = vPC[2].u.operand;
         int value = vPC[3].u.operand;
+        int direct = vPC[8].u.operand;
 
         JSValue baseValue = callFrame->r(base).jsValue();
         Identifier& ident = callFrame->codeBlock()->identifier(property);
         PutPropertySlot slot;
 
         JSValue baseValue = callFrame->r(base).jsValue();
         Identifier& ident = callFrame->codeBlock()->identifier(property);
         PutPropertySlot slot;
-        baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
+        if (direct) {
+            baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot);
+            ASSERT(slot.base() == baseValue);
+        } else
+            baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
         CHECK_FOR_EXCEPTION();
 
         vPC += OPCODE_LENGTH(op_put_by_id_generic);
         CHECK_FOR_EXCEPTION();
 
         vPC += OPCODE_LENGTH(op_put_by_id_generic);
@@ -2884,6 +3399,29 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         vPC += OPCODE_LENGTH(op_jnlesseq);
         NEXT_INSTRUCTION();
     }
         vPC += OPCODE_LENGTH(op_jnlesseq);
         NEXT_INSTRUCTION();
     }
+    DEFINE_OPCODE(op_jlesseq) {
+        /* jlesseq 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 the result of the comparison is true.
+         */
+        JSValue src1 = callFrame->r(vPC[1].u.operand).jsValue();
+        JSValue src2 = callFrame->r(vPC[2].u.operand).jsValue();
+        int target = vPC[3].u.operand;
+        
+        bool result = jsLessEq(callFrame, src1, src2);
+        CHECK_FOR_EXCEPTION();
+        
+        if (result) {
+            vPC += target;
+            NEXT_INSTRUCTION();
+        }
+        
+        vPC += OPCODE_LENGTH(op_jlesseq);
+        NEXT_INSTRUCTION();
+    }
     DEFINE_OPCODE(op_switch_imm) {
         /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
 
     DEFINE_OPCODE(op_switch_imm) {
         /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
 
@@ -2924,10 +3462,10 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
             vPC += defaultOffset;
         else {
             UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
             vPC += defaultOffset;
         else {
             UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
-            if (value->size() != 1)
+            if (value->length() != 1)
                 vPC += defaultOffset;
             else
                 vPC += defaultOffset;
             else
-                vPC += callFrame->codeBlock()->characterSwitchJumpTable(tableIndex).offsetForValue(value->data()[0], defaultOffset);
+                vPC += callFrame->codeBlock()->characterSwitchJumpTable(tableIndex).offsetForValue(value->characters()[0], defaultOffset);
         }
         NEXT_INSTRUCTION();
     }
         }
         NEXT_INSTRUCTION();
     }
@@ -3179,10 +3717,8 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
                     CHECK_FOR_EXCEPTION();
                 }
             } else {
                     CHECK_FOR_EXCEPTION();
                 }
             } else {
-                if (!arguments.isObject()) {
-                    exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock());
-                    goto vm_throw;
-                }
+                exceptionValue = createInvalidParamError(callFrame, "Function.prototype.apply", arguments, vPC - callFrame->codeBlock()->instructions().begin(), callFrame->codeBlock());
+                goto vm_throw;
             }
         }
         CHECK_FOR_EXCEPTION();
             }
         }
         CHECK_FOR_EXCEPTION();
@@ -3326,7 +3862,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
         JSValue returnValue = callFrame->r(result).jsValue();
 
 
         JSValue returnValue = callFrame->r(result).jsValue();
 
-        vPC = callFrame->returnPC();
+        vPC = callFrame->returnVPC();
         int dst = callFrame->returnValueRegister();
         callFrame = callFrame->callerFrame();
         
         int dst = callFrame->returnValueRegister();
         callFrame = callFrame->callerFrame();
         
@@ -3486,7 +4022,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
 
             callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
             vPC = newCodeBlock->instructions().begin();
 
             callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
             vPC = newCodeBlock->instructions().begin();
-
 #if ENABLE(OPCODE_STATS)
             OpcodeStats::resetLastInstruction();
 #endif
 #if ENABLE(OPCODE_STATS)
             OpcodeStats::resetLastInstruction();
 #endif
@@ -3542,7 +4077,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         int src = vPC[2].u.operand;
         int count = vPC[3].u.operand;
 
         int src = vPC[2].u.operand;
         int count = vPC[3].u.operand;
 
-        callFrame->r(dst) = jsString(callFrame, &callFrame->registers()[src], count);
+        callFrame->r(dst) = concatenateStrings(callFrame, &callFrame->registers()[src], count);
         CHECK_FOR_EXCEPTION();
         vPC += OPCODE_LENGTH(op_strcat);
 
         CHECK_FOR_EXCEPTION();
         vPC += OPCODE_LENGTH(op_strcat);
 
@@ -3665,7 +4200,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         vPC += target;
         NEXT_INSTRUCTION();
     }
         vPC += target;
         NEXT_INSTRUCTION();
     }
-#if HAVE(COMPUTED_GOTO)
+#if ENABLE(COMPUTED_GOTO_INTERPRETER)
     // Appease GCC
     goto *(&&skip_new_scope);
 #endif
     // Appease GCC
     goto *(&&skip_new_scope);
 #endif
@@ -3681,7 +4216,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         vPC += OPCODE_LENGTH(op_push_new_scope);
         NEXT_INSTRUCTION();
     }
         vPC += OPCODE_LENGTH(op_push_new_scope);
         NEXT_INSTRUCTION();
     }
-#if HAVE(COMPUTED_GOTO)
+#if ENABLE(COMPUTED_GOTO_INTERPRETER)
     skip_new_scope:
 #endif
     DEFINE_OPCODE(op_catch) {
     skip_new_scope:
 #endif
     DEFINE_OPCODE(op_catch) {
@@ -3892,14 +4427,14 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
         NEXT_INSTRUCTION();
     }
     }
         NEXT_INSTRUCTION();
     }
     }
-#if !HAVE(COMPUTED_GOTO)
+#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
     } // iterator loop ends
 #endif
     } // iterator loop ends
 #endif
-#endif // USE(INTERPRETER)
     #undef NEXT_INSTRUCTION
     #undef DEFINE_OPCODE
     #undef CHECK_FOR_EXCEPTION
     #undef CHECK_FOR_TIMEOUT
     #undef NEXT_INSTRUCTION
     #undef DEFINE_OPCODE
     #undef CHECK_FOR_EXCEPTION
     #undef CHECK_FOR_TIMEOUT
+#endif // ENABLE(INTERPRETER)
 }
 
 JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* function) const
 }
 
 JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* function) const
@@ -3961,8 +4496,17 @@ void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intp
     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
     if (!callerCodeBlock)
         return;
     CodeBlock* callerCodeBlock = callerFrame->codeBlock();
     if (!callerCodeBlock)
         return;
-
-    unsigned bytecodeOffset = bytecodeOffsetForPC(callerFrame, callerCodeBlock, callFrame->returnPC());
+    unsigned bytecodeOffset = 0;
+#if ENABLE(INTERPRETER)
+    if (!callerFrame->globalData().canUseJIT())
+        bytecodeOffset = bytecodeOffsetForPC(callerFrame, callerCodeBlock, callFrame->returnVPC());
+#if ENABLE(JIT)
+    else
+        bytecodeOffset = bytecodeOffsetForPC(callerFrame, callerCodeBlock, callFrame->returnPC());
+#endif
+#else
+    bytecodeOffset = bytecodeOffsetForPC(callerFrame, callerCodeBlock, callFrame->returnPC());
+#endif
     lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(callerFrame, bytecodeOffset - 1);
     sourceID = callerCodeBlock->ownerExecutable()->sourceID();
     sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
     lineNumber = callerCodeBlock->lineNumberForBytecodeOffset(callerFrame, bytecodeOffset - 1);
     sourceID = callerCodeBlock->ownerExecutable()->sourceID();
     sourceURL = callerCodeBlock->ownerExecutable()->sourceURL();
index 5ddf58e658f119b84472ccabb38c0e3a84bd6eb6..2bcc82ffdfaa06935ce25c1389320ab9b657c6d1 100644 (file)
@@ -66,7 +66,7 @@ namespace JSC {
 
     // We use a smaller reentrancy limit on iPhone because of the high amount of
     // stack space required on the web thread.
 
     // We use a smaller reentrancy limit on iPhone because of the high amount of
     // stack space required on the web thread.
-    enum { MaxMainThreadReentryDepth = 100, MaxSecondaryThreadReentryDepth = 32 };
+    enum { MaxLargeThreadReentryDepth = 100, MaxSmallThreadReentryDepth = 32 };
 
     class Interpreter : public FastAllocBase {
         friend class JIT;
 
     class Interpreter : public FastAllocBase {
         friend class JIT;
@@ -78,7 +78,7 @@ namespace JSC {
         
         Opcode getOpcode(OpcodeID id)
         {
         
         Opcode getOpcode(OpcodeID id)
         {
-            #if HAVE(COMPUTED_GOTO)
+            #if ENABLE(COMPUTED_GOTO_INTERPRETER)
                 return m_opcodeTable[id];
             #else
                 return id;
                 return m_opcodeTable[id];
             #else
                 return id;
@@ -87,7 +87,7 @@ namespace JSC {
 
         OpcodeID getOpcodeID(Opcode opcode)
         {
 
         OpcodeID getOpcodeID(Opcode opcode)
         {
-            #if HAVE(COMPUTED_GOTO)
+            #if ENABLE(COMPUTED_GOTO_INTERPRETER)
                 ASSERT(isOpcode(opcode));
                 return m_opcodeIDTable.get(opcode);
             #else
                 ASSERT(isOpcode(opcode));
                 return m_opcodeIDTable.get(opcode);
             #else
@@ -125,10 +125,11 @@ namespace JSC {
 
         JSValue execute(EvalExecutable*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValue* exception);
 
 
         JSValue execute(EvalExecutable*, CallFrame*, JSObject* thisObject, int globalRegisterOffset, ScopeChainNode*, JSValue* exception);
 
-#if USE(INTERPRETER)
+#if ENABLE(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 bool resolve(CallFrame*, Instruction*, JSValue& exceptionValue);
         NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValue& exceptionValue);
         NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue& exceptionValue);
+        NEVER_INLINE bool resolveGlobalDynamic(CallFrame*, Instruction*, JSValue& exceptionValue);
         NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
         NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
         NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
         NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
         NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue& exceptionValue);
         NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
@@ -137,7 +138,7 @@ namespace JSC {
         void uncacheGetByID(CodeBlock*, Instruction* vPC);
         void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
         void uncachePutByID(CodeBlock*, Instruction* vPC);        
         void uncacheGetByID(CodeBlock*, Instruction* vPC);
         void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue baseValue, const PutPropertySlot&);
         void uncachePutByID(CodeBlock*, Instruction* vPC);        
-#endif
+#endif // ENABLE(INTERPRETER)
 
         NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
 
 
         NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue, unsigned& bytecodeOffset, CodeBlock*&);
 
@@ -160,7 +161,7 @@ namespace JSC {
 
         RegisterFile m_registerFile;
         
 
         RegisterFile m_registerFile;
         
-#if HAVE(COMPUTED_GOTO)
+#if ENABLE(COMPUTED_GOTO_INTERPRETER)
         Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
         HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
 #endif
         Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
         HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
 #endif
index 510effe0dd6c09a83584dc748969412823c52a17..63ea5b371c4e5af90743aa44eed59db63b0fc000 100644 (file)
@@ -29,6 +29,8 @@
 #include "config.h"
 #include "RegisterFile.h"
 
 #include "config.h"
 #include "RegisterFile.h"
 
+#include "JSGlobalObject.h"
+
 namespace JSC {
 
 RegisterFile::~RegisterFile()
 namespace JSC {
 
 RegisterFile::~RegisterFile()
@@ -56,4 +58,19 @@ void RegisterFile::releaseExcessCapacity()
     m_maxUsed = m_start;
 }
 
     m_maxUsed = m_start;
 }
 
+void RegisterFile::setGlobalObject(JSGlobalObject* globalObject)
+{
+    m_globalObject = globalObject;
+}
+
+bool RegisterFile::clearGlobalObject(JSGlobalObject* globalObject)
+{
+    return m_globalObject.clear(globalObject);
+}
+
+JSGlobalObject* RegisterFile::globalObject()
+{
+    return m_globalObject.get();
+}
+
 } // namespace JSC
 } // namespace JSC
index 1fc4f828b48acc1b1a4772b00729882006ad23e3..def9e2549195a0def3c7374cd490fc5984986485 100644 (file)
@@ -32,6 +32,7 @@
 #include "Collector.h"
 #include "ExecutableAllocator.h"
 #include "Register.h"
 #include "Collector.h"
 #include "ExecutableAllocator.h"
 #include "Register.h"
+#include "WeakGCPtr.h"
 #include <stdio.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/VMTags.h>
 #include <stdio.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/VMTags.h>
@@ -124,8 +125,9 @@ namespace JSC {
         Register* end() const { return m_end; }
         size_t size() const { return m_end - m_start; }
 
         Register* end() const { return m_end; }
         size_t size() const { return m_end - m_start; }
 
-        void setGlobalObject(JSGlobalObject* globalObject) { m_globalObject = globalObject; }
-        JSGlobalObject* globalObject() { return m_globalObject; }
+        void setGlobalObject(JSGlobalObject*);
+        bool clearGlobalObject(JSGlobalObject*);
+        JSGlobalObject* globalObject();
 
         bool grow(Register* newEnd);
         void shrink(Register* newEnd);
 
         bool grow(Register* newEnd);
         void shrink(Register* newEnd);
@@ -153,7 +155,7 @@ namespace JSC {
         Register* m_commitEnd;
 #endif
 
         Register* m_commitEnd;
 #endif
 
-        JSGlobalObject* m_globalObject; // The global object whose vars are currently stored in the register file.
+        WeakGCPtr<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.
     };
 
     // FIXME: Add a generic getpagesize() to WTF, then move this function to WTF as well.
@@ -166,7 +168,6 @@ namespace JSC {
         , m_end(0)
         , m_max(0)
         , m_buffer(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));
     {
         // Verify that our values will play nice with mmap and VirtualAlloc.
         ASSERT(isPageAligned(maxGlobals));
index f6b27ec2ab4ef2e3466b90ede62babde16b73116..5e10e863d49f6ddd899a33709c0540dfa94aa125 100644 (file)
@@ -33,6 +33,42 @@ namespace JSC {
 
 size_t ExecutableAllocator::pageSize = 0;
 
 
 size_t ExecutableAllocator::pageSize = 0;
 
+#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
+
+#if CPU(ARM_TRADITIONAL) && OS(LINUX) && COMPILER(RVCT)
+__asm void ExecutableAllocator::cacheFlush(void* code, size_t size)
+{
+    ARM
+    push {r7}
+    add r1, r1, r0
+    mov r7, #0xf0000
+    add r7, r7, #0x2
+    mov r2, #0x0
+    svc #0x0
+    pop {r7}
+    bx lr
+}
+#endif
+
 }
 
 #endif // HAVE(ASSEMBLER)
 }
 
 #endif // HAVE(ASSEMBLER)
index 1fb8ff744b544b4c9575e882a599b404cd9ab489..445852b12a21d545e82f924f6a2e63a44f10d5d1 100644 (file)
 #include <e32std.h>
 #endif
 
 #include <e32std.h>
 #endif
 
+#if CPU(MIPS) && OS(LINUX)
+#include <sys/cachectl.h>
+#endif
+
 #if OS(WINCE)
 // From pkfuncs.h (private header file from the Platform Builder)
 #define CACHE_SYNC_ALL 0x07F
 #if OS(WINCE)
 // From pkfuncs.h (private header file from the Platform Builder)
 #define CACHE_SYNC_ALL 0x07F
@@ -147,12 +151,20 @@ public:
     {
         if (!pageSize)
             intializePageSize();
     {
         if (!pageSize)
             intializePageSize();
-        m_smallAllocationPool = ExecutablePool::create(JIT_ALLOCATOR_LARGE_ALLOC_SIZE);
+        if (isValid())
+            m_smallAllocationPool = ExecutablePool::create(JIT_ALLOCATOR_LARGE_ALLOC_SIZE);
+#if !ENABLE(INTERPRETER)
+        else
+            CRASH();
+#endif
     }
 
     }
 
+    bool isValid() const;
+    
     PassRefPtr<ExecutablePool> poolForSize(size_t n)
     {
         // Try to fit in the existing small allocator
     PassRefPtr<ExecutablePool> poolForSize(size_t n)
     {
         // Try to fit in the existing small allocator
+        ASSERT(m_smallAllocationPool);
         if (n < m_smallAllocationPool->available())
             return m_smallAllocationPool;
 
         if (n < m_smallAllocationPool->available())
             return m_smallAllocationPool;
 
@@ -190,6 +202,32 @@ public:
     static void cacheFlush(void*, size_t)
     {
     }
     static void cacheFlush(void*, size_t)
     {
     }
+#elif CPU(MIPS)
+    static void cacheFlush(void* code, size_t size)
+    {
+#if COMPILER(GCC) && (GCC_VERSION >= 40300)
+#if WTF_MIPS_ISA_REV(2) && (GCC_VERSION < 40403)
+        int lineSize;
+        asm("rdhwr %0, $1" : "=r" (lineSize));
+        //
+        // Modify "start" and "end" to avoid GCC 4.3.0-4.4.2 bug in
+        // mips_expand_synci_loop that may execute synci one more time.
+        // "start" points to the fisrt byte of the cache line.
+        // "end" points to the last byte of the line before the last cache line.
+        // Because size is always a multiple of 4, this is safe to set
+        // "end" to the last byte.
+        //
+        intptr_t start = reinterpret_cast<intptr_t>(code) & (-lineSize);
+        intptr_t end = ((reinterpret_cast<intptr_t>(code) + size - 1) & (-lineSize)) - 1;
+        __builtin___clear_cache(reinterpret_cast<char*>(start), reinterpret_cast<char*>(end));
+#else
+        intptr_t end = reinterpret_cast<intptr_t>(code) + size;
+        __builtin___clear_cache(reinterpret_cast<char*>(code), reinterpret_cast<char*>(end));
+#endif
+#else
+        _flush_cache(reinterpret_cast<char*>(code), size, BCACHE);
+#endif
+    }
 #elif CPU(ARM_THUMB2) && OS(IPHONE_OS)
     static void cacheFlush(void* code, size_t size)
     {
 #elif CPU(ARM_THUMB2) && OS(IPHONE_OS)
     static void cacheFlush(void* code, size_t size)
     {
@@ -217,7 +255,9 @@ public:
     {
         User::IMB_Range(code, static_cast<char*>(code) + size);
     }
     {
         User::IMB_Range(code, static_cast<char*>(code) + size);
     }
-#elif CPU(ARM_TRADITIONAL) && OS(LINUX)
+#elif CPU(ARM_TRADITIONAL) && OS(LINUX) && COMPILER(RVCT)
+    static __asm void cacheFlush(void* code, size_t size);
+#elif CPU(ARM_TRADITIONAL) && OS(LINUX) && COMPILER(GCC)
     static void cacheFlush(void* code, size_t size)
     {
         asm volatile (
     static void cacheFlush(void* code, size_t size)
     {
         asm volatile (
index dd1db4e24ab85df7d8ff8e7c22d89489af8b4918..4c30058484d1a0ee93a2331c79c7bb811454efbe 100644 (file)
 
 #include "ExecutableAllocator.h"
 
 
 #include "ExecutableAllocator.h"
 
-#include <errno.h>
+#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
 
 
-#if ENABLE(ASSEMBLER) && OS(DARWIN) && CPU(X86_64)
+#include <errno.h>
 
 #include "TCSpinLock.h"
 
 #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>
 
 #include <sys/mman.h>
 #include <unistd.h>
 #include <wtf/AVLTree.h>
 #include <wtf/VMTags.h>
 
+    #define MMAP_FLAGS (MAP_PRIVATE | MAP_ANON | MAP_JIT)
+
 using namespace WTF;
 
 namespace JSC {
 
 using namespace WTF;
 
 namespace JSC {
 
-#define TWO_GB (2u * 1024u * 1024u * 1024u)
-#define SIXTEEN_MB (16u * 1024u * 1024u)
+#if CPU(X86_64)
+    // These limits suitable on 64-bit platforms (particularly x86-64, where we require all jumps to have a 2Gb max range).
+    #define VM_POOL_SIZE (2u * 1024u * 1024u * 1024u) // 2Gb
+    #define COALESCE_LIMIT (16u * 1024u * 1024u) // 16Mb
+#else
+    // These limits are hopefully sensible on embedded platforms.
+    #define VM_POOL_SIZE (32u * 1024u * 1024u) // 32Mb
+    #define COALESCE_LIMIT (4u * 1024u * 1024u) // 4Mb
+#endif
+
+// ASLR currently only works on darwin (due to arc4random) & 64-bit (due to address space size).
+#define VM_POOL_ASLR (OS(DARWIN) && CPU(X86_64))
 
 // FreeListEntry describes a free chunk of memory, stored in the freeList.
 struct FreeListEntry {
 
 // FreeListEntry describes a free chunk of memory, stored in the freeList.
 struct FreeListEntry {
@@ -128,6 +138,13 @@ class FixedVMPoolAllocator
     {
         while (madvise(position, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
     }
     {
         while (madvise(position, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
     }
+#elif HAVE(MADV_FREE)
+    void release(void* position, size_t size)
+    {
+        while (madvise(position, size, MADV_FREE) == -1 && errno == EAGAIN) { }
+    }
+    
+    void reuse(void*, size_t) {}
 #elif HAVE(MADV_DONTNEED)
     void release(void* position, size_t size)
     {
 #elif HAVE(MADV_DONTNEED)
     void release(void* position, size_t size)
     {
@@ -291,24 +308,39 @@ public:
         // 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).
         // 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);
+        intptr_t randomLocation = 0;
+#if VM_POOL_ASLR
+        randomLocation = arc4random() & ((1 << 25) - 1);
         randomLocation += (1 << 24);
         randomLocation <<= 21;
         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();
+#endif
+        m_base = mmap(reinterpret_cast<void*>(randomLocation), m_totalHeapSize, INITIAL_PROTECTION_FLAGS, MMAP_FLAGS, VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, 0);
 
 
-        // 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));
+        if (m_base == MAP_FAILED) {
+#if ENABLE(INTERPRETER)
+            m_base = 0;
+#else
+            CRASH();
+#endif
+        } else {
+            // 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* alloc(size_t size)
     {
+#if ENABLE(INTERPRETER)
+        if (!m_base)
+            return 0;
+#else
+        ASSERT(m_base);
+#endif
         void* result;
 
         // Freed allocations of the common size are not stored back into the main
         void* result;
 
         // Freed allocations of the common size are not stored back into the main
@@ -371,6 +403,7 @@ public:
 
     void free(void* pointer, size_t size)
     {
 
     void free(void* pointer, size_t size)
     {
+        ASSERT(m_base);
         // 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));
         // 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));
@@ -387,12 +420,14 @@ public:
         // 16MB of allocations have been freed, sweep m_freeList
         // coalescing any neighboring fragments.
         m_countFreedSinceLastCoalesce += size;
         // 16MB of allocations have been freed, sweep m_freeList
         // coalescing any neighboring fragments.
         m_countFreedSinceLastCoalesce += size;
-        if (m_countFreedSinceLastCoalesce >= SIXTEEN_MB) {
+        if (m_countFreedSinceLastCoalesce >= COALESCE_LIMIT) {
             m_countFreedSinceLastCoalesce = 0;
             coalesceFreeSpace();
         }
     }
 
             m_countFreedSinceLastCoalesce = 0;
             coalesceFreeSpace();
         }
     }
 
+    bool isValid() const { return !!m_base; }
+
 private:
 
 #ifndef NDEBUG
 private:
 
 #ifndef NDEBUG
@@ -424,19 +459,27 @@ void ExecutableAllocator::intializePageSize()
 static FixedVMPoolAllocator* allocator = 0;
 static SpinLock spinlock = SPINLOCK_INITIALIZER;
 
 static FixedVMPoolAllocator* allocator = 0;
 static SpinLock spinlock = SPINLOCK_INITIALIZER;
 
+bool ExecutableAllocator::isValid() const
+{
+    SpinLockHolder lock_holder(&spinlock);
+    if (!allocator)
+        allocator = new FixedVMPoolAllocator(JIT_ALLOCATOR_LARGE_ALLOC_SIZE, VM_POOL_SIZE);
+    return allocator->isValid();
+}
+
 ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size)
 {
 ExecutablePool::Allocation ExecutablePool::systemAlloc(size_t size)
 {
-  SpinLockHolder lock_holder(&spinlock);
+    SpinLockHolder lock_holder(&spinlock);
 
     if (!allocator)
 
     if (!allocator)
-        allocator = new FixedVMPoolAllocator(JIT_ALLOCATOR_LARGE_ALLOC_SIZE, TWO_GB);
+        allocator = new FixedVMPoolAllocator(JIT_ALLOCATOR_LARGE_ALLOC_SIZE, VM_POOL_SIZE);
     ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(allocator->alloc(size)), size};
     return alloc;
 }
 
 void ExecutablePool::systemRelease(const ExecutablePool::Allocation& allocation) 
 {
     ExecutablePool::Allocation alloc = {reinterpret_cast<char*>(allocator->alloc(size)), size};
     return alloc;
 }
 
 void ExecutablePool::systemRelease(const ExecutablePool::Allocation& allocation) 
 {
-  SpinLockHolder lock_holder(&spinlock);
+    SpinLockHolder lock_holder(&spinlock);
 
     ASSERT(allocator);
     allocator->free(allocation.pages, allocation.size);
 
     ASSERT(allocator);
     allocator->free(allocation.pages, allocation.size);
index 06375adb537f2ed0713118e58dae761772de9676..9de8236d66a7671779990dfc77d9c61d88beb6a0 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "ExecutableAllocator.h"
 
 
 #include "ExecutableAllocator.h"
 
-#if ENABLE(ASSEMBLER) && OS(UNIX) && !OS(SYMBIAN)
+#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) && !OS(WINDOWS) && !OS(SYMBIAN)
 
 #include <sys/mman.h>
 #include <unistd.h>
 
 #include <sys/mman.h>
 #include <unistd.h>
@@ -35,8 +35,6 @@
 
 namespace JSC {
 
 
 namespace JSC {
 
-#if !(OS(DARWIN) && CPU(X86_64))
-
 void ExecutableAllocator::intializePageSize()
 {
     ExecutableAllocator::pageSize = getpagesize();
 void ExecutableAllocator::intializePageSize()
 {
     ExecutableAllocator::pageSize = getpagesize();
@@ -57,29 +55,26 @@ void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc)
     ASSERT_UNUSED(result, !result);
 }
 
     ASSERT_UNUSED(result, !result);
 }
 
-#endif // !(OS(DARWIN) && CPU(X86_64))
-
-#if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
-void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSeting setting)
+bool ExecutableAllocator::isValid() const
 {
 {
-    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);
+    return true;
+}
 
 
-    mprotect(pageStart, size, (setting == Writable) ? PROTECTION_FLAGS_RW : PROTECTION_FLAGS_RX);
+#if CPU(ARM_TRADITIONAL) && OS(LINUX) && COMPILER(RVCT)
+__asm void ExecutableAllocator::cacheFlush(void* code, size_t size)
+{
+    ARM
+    push {r7}
+    add r1, r1, r0
+    mov r7, #0xf0000
+    add r7, r7, #0x2
+    mov r2, #0x0
+    svc #0x0
+    pop {r7}
+    bx lr
 }
 #endif
 
 }
 
 }
 #endif
 
 }
 
-#endif // HAVE(ASSEMBLER)
+#endif
index e82975c9c25fabf50d00005a6677e47d1ba7249a..9028f506ef7c003847f16bd5313397fc204714ac 100644 (file)
@@ -22,7 +22,7 @@
 
 #include "ExecutableAllocator.h"
 
 
 #include "ExecutableAllocator.h"
 
-#if ENABLE(ASSEMBLER) && OS(SYMBIAN)
+#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) && OS(SYMBIAN)
 
 #include <e32hal.h>
 #include <e32std.h>
 
 #include <e32hal.h>
 #include <e32std.h>
index e38323c5fddd394628cd0d8fe6842a6c53c479c5..2b13529ee03a2bdea589f296540e751a15cfda15 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "ExecutableAllocator.h"
 
 
 #include "ExecutableAllocator.h"
 
-#if ENABLE(ASSEMBLER) && OS(WINDOWS)
+#if ENABLE(EXECUTABLE_ALLOCATOR_DEMAND) && OS(WINDOWS)
 
 #include "windows.h"
 
 
 #include "windows.h"
 
@@ -54,6 +54,11 @@ void ExecutablePool::systemRelease(const ExecutablePool::Allocation& alloc)
     VirtualFree(alloc.pages, 0, MEM_RELEASE); 
 }
 
     VirtualFree(alloc.pages, 0, MEM_RELEASE); 
 }
 
+bool ExecutableAllocator::isValid() const
+{
+    return true;
+}
+
 #if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
 #error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform."
 #endif
 #if ENABLE(ASSEMBLER_WX_EXCLUSIVE)
 #error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform."
 #endif
index c0da66df595eaf4914858fd3f4f25d6f1b9adcc9..00f0d23e715697f00ad5f30ef1bfa1d841e8b345 100644 (file)
@@ -200,7 +200,6 @@ void JIT::privateCompileMainPass()
         DEFINE_BINARY_OP(op_in)
         DEFINE_BINARY_OP(op_less)
         DEFINE_BINARY_OP(op_lesseq)
         DEFINE_BINARY_OP(op_in)
         DEFINE_BINARY_OP(op_less)
         DEFINE_BINARY_OP(op_lesseq)
-        DEFINE_BINARY_OP(op_urshift)
         DEFINE_UNARY_OP(op_is_boolean)
         DEFINE_UNARY_OP(op_is_function)
         DEFINE_UNARY_OP(op_is_number)
         DEFINE_UNARY_OP(op_is_boolean)
         DEFINE_UNARY_OP(op_is_function)
         DEFINE_UNARY_OP(op_is_number)
@@ -251,6 +250,7 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_jneq_ptr)
         DEFINE_OP(op_jnless)
         DEFINE_OP(op_jless)
         DEFINE_OP(op_jneq_ptr)
         DEFINE_OP(op_jnless)
         DEFINE_OP(op_jless)
+        DEFINE_OP(op_jlesseq)
         DEFINE_OP(op_jnlesseq)
         DEFINE_OP(op_jsr)
         DEFINE_OP(op_jtrue)
         DEFINE_OP(op_jnlesseq)
         DEFINE_OP(op_jsr)
         DEFINE_OP(op_jtrue)
@@ -298,10 +298,12 @@ void JIT::privateCompileMainPass()
         DEFINE_OP(op_resolve)
         DEFINE_OP(op_resolve_base)
         DEFINE_OP(op_resolve_global)
         DEFINE_OP(op_resolve)
         DEFINE_OP(op_resolve_base)
         DEFINE_OP(op_resolve_global)
+        DEFINE_OP(op_resolve_global_dynamic)
         DEFINE_OP(op_resolve_skip)
         DEFINE_OP(op_resolve_with_base)
         DEFINE_OP(op_ret)
         DEFINE_OP(op_rshift)
         DEFINE_OP(op_resolve_skip)
         DEFINE_OP(op_resolve_with_base)
         DEFINE_OP(op_ret)
         DEFINE_OP(op_rshift)
+        DEFINE_OP(op_urshift)
         DEFINE_OP(op_sret)
         DEFINE_OP(op_strcat)
         DEFINE_OP(op_stricteq)
         DEFINE_OP(op_sret)
         DEFINE_OP(op_strcat)
         DEFINE_OP(op_stricteq)
@@ -322,6 +324,16 @@ void JIT::privateCompileMainPass()
         case op_get_by_id_proto_list:
         case op_get_by_id_self:
         case op_get_by_id_self_list:
         case op_get_by_id_proto_list:
         case op_get_by_id_self:
         case op_get_by_id_self_list:
+        case op_get_by_id_getter_chain:
+        case op_get_by_id_getter_proto:
+        case op_get_by_id_getter_proto_list:
+        case op_get_by_id_getter_self:
+        case op_get_by_id_getter_self_list:
+        case op_get_by_id_custom_chain:
+        case op_get_by_id_custom_proto:
+        case op_get_by_id_custom_proto_list:
+        case op_get_by_id_custom_self:
+        case op_get_by_id_custom_self_list:
         case op_get_string_length:
         case op_put_by_id_generic:
         case op_put_by_id_replace:
         case op_get_string_length:
         case op_put_by_id_generic:
         case op_put_by_id_replace:
@@ -353,9 +365,7 @@ void JIT::privateCompileSlowCases()
     Instruction* instructionsBegin = m_codeBlock->instructions().begin();
 
     m_propertyAccessInstructionIndex = 0;
     Instruction* instructionsBegin = m_codeBlock->instructions().begin();
 
     m_propertyAccessInstructionIndex = 0;
-#if USE(JSVALUE32_64)
     m_globalResolveInfoIndex = 0;
     m_globalResolveInfoIndex = 0;
-#endif
     m_callLinkInfoIndex = 0;
 
     for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) {
     m_callLinkInfoIndex = 0;
 
     for (Vector<SlowCaseEntry>::iterator iter = m_slowCases.begin(); iter != m_slowCases.end();) {
@@ -392,6 +402,7 @@ void JIT::privateCompileSlowCases()
         DEFINE_SLOWCASE_OP(op_jfalse)
         DEFINE_SLOWCASE_OP(op_jnless)
         DEFINE_SLOWCASE_OP(op_jless)
         DEFINE_SLOWCASE_OP(op_jfalse)
         DEFINE_SLOWCASE_OP(op_jnless)
         DEFINE_SLOWCASE_OP(op_jless)
+        DEFINE_SLOWCASE_OP(op_jlesseq)
         DEFINE_SLOWCASE_OP(op_jnlesseq)
         DEFINE_SLOWCASE_OP(op_jtrue)
         DEFINE_SLOWCASE_OP(op_loop_if_less)
         DEFINE_SLOWCASE_OP(op_jnlesseq)
         DEFINE_SLOWCASE_OP(op_jtrue)
         DEFINE_SLOWCASE_OP(op_loop_if_less)
@@ -414,10 +425,10 @@ void JIT::privateCompileSlowCases()
         DEFINE_SLOWCASE_OP(op_pre_inc)
         DEFINE_SLOWCASE_OP(op_put_by_id)
         DEFINE_SLOWCASE_OP(op_put_by_val)
         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)
         DEFINE_SLOWCASE_OP(op_resolve_global)
-#endif
+        DEFINE_SLOWCASE_OP(op_resolve_global_dynamic)
         DEFINE_SLOWCASE_OP(op_rshift)
         DEFINE_SLOWCASE_OP(op_rshift)
+        DEFINE_SLOWCASE_OP(op_urshift)
         DEFINE_SLOWCASE_OP(op_stricteq)
         DEFINE_SLOWCASE_OP(op_sub)
         DEFINE_SLOWCASE_OP(op_to_jsnumber)
         DEFINE_SLOWCASE_OP(op_stricteq)
         DEFINE_SLOWCASE_OP(op_sub)
         DEFINE_SLOWCASE_OP(op_to_jsnumber)
@@ -582,7 +593,7 @@ 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.
     // 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.get());
+    RepatchBuffer repatchBuffer(callLinkInfo->ownerCodeBlock);
 #if USE(JSVALUE32_64)
     repatchBuffer.repatch(callLinkInfo->hotPathBegin, 0);
 #else
 #if USE(JSVALUE32_64)
     repatchBuffer.repatch(callLinkInfo->hotPathBegin, 0);
 #else
@@ -607,7 +618,7 @@ void JIT::linkCall(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* ca
     }
 
     // patch the call so we do not continue to try to link.
     }
 
     // patch the call so we do not continue to try to link.
-    repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs.ctiVirtualCall());
+    repatchBuffer.relink(callLinkInfo->callReturnLocation, globalData->jitStubs->ctiVirtualCall());
 }
 #endif // ENABLE(JIT_OPTIMIZE_CALL)
 
 }
 #endif // ENABLE(JIT_OPTIMIZE_CALL)
 
index 8e0c9acd5260af7f07d6d4ec1910088983ae5474..83f2c0dfb2165ba4c4b382c42812a70a24de781b 100644 (file)
--- a/jit/JIT.h
+++ b/jit/JIT.h
@@ -26,8 +26,6 @@
 #ifndef JIT_h
 #define JIT_h
 
 #ifndef JIT_h
 #define JIT_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(JIT)
 
 // We've run into some problems where changing the size of the class JIT leads to
 #if ENABLE(JIT)
 
 // We've run into some problems where changing the size of the class JIT leads to
 
 #include "CodeBlock.h"
 #include "Interpreter.h"
 
 #include "CodeBlock.h"
 #include "Interpreter.h"
-#include "JITCode.h"
-#include "JITStubs.h"
+#include "JSInterfaceJIT.h"
 #include "Opcode.h"
 #include "Opcode.h"
-#include "RegisterFile.h"
-#include "MacroAssembler.h"
 #include "Profiler.h"
 #include <bytecode/SamplingTool.h>
 #include "Profiler.h"
 #include <bytecode/SamplingTool.h>
-#include <wtf/AlwaysInline.h>
-#include <wtf/Vector.h>
 
 namespace JSC {
 
 
 namespace JSC {
 
@@ -172,106 +165,13 @@ namespace JSC {
     void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction);
     void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction);
 
     void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction);
     void ctiPatchCallByReturnAddress(CodeBlock* codeblock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction);
 
-    class JIT : private MacroAssembler {
+    class JIT : private JSInterfaceJIT {
         friend class JITStubCall;
 
         using MacroAssembler::Jump;
         using MacroAssembler::JumpList;
         using MacroAssembler::Label;
 
         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 CPU(X86_64)
-        static const RegisterID returnValueRegister = X86Registers::eax;
-        static const RegisterID cachedResultRegister = X86Registers::eax;
-        static const RegisterID firstArgumentRegister = X86Registers::edi;
-
-        static const RegisterID timeoutCheckRegister = X86Registers::r12;
-        static const RegisterID callFrameRegister = X86Registers::r13;
-        static const RegisterID tagTypeNumberRegister = X86Registers::r14;
-        static const RegisterID tagMaskRegister = X86Registers::r15;
-
-        static const RegisterID regT0 = X86Registers::eax;
-        static const RegisterID regT1 = X86Registers::edx;
-        static const RegisterID regT2 = X86Registers::ecx;
-        static const RegisterID regT3 = X86Registers::ebx;
-
-        static const FPRegisterID fpRegT0 = X86Registers::xmm0;
-        static const FPRegisterID fpRegT1 = X86Registers::xmm1;
-        static const FPRegisterID fpRegT2 = X86Registers::xmm2;
-#elif CPU(X86)
-        static const RegisterID returnValueRegister = X86Registers::eax;
-        static const RegisterID cachedResultRegister = X86Registers::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 = X86Registers::ecx;
-
-        static const RegisterID timeoutCheckRegister = X86Registers::esi;
-        static const RegisterID callFrameRegister = X86Registers::edi;
-
-        static const RegisterID regT0 = X86Registers::eax;
-        static const RegisterID regT1 = X86Registers::edx;
-        static const RegisterID regT2 = X86Registers::ecx;
-        static const RegisterID regT3 = X86Registers::ebx;
-
-        static const FPRegisterID fpRegT0 = X86Registers::xmm0;
-        static const FPRegisterID fpRegT1 = X86Registers::xmm1;
-        static const FPRegisterID fpRegT2 = X86Registers::xmm2;
-#elif CPU(ARM_THUMB2)
-        static const RegisterID returnValueRegister = ARMRegisters::r0;
-        static const RegisterID cachedResultRegister = ARMRegisters::r0;
-        static const RegisterID firstArgumentRegister = ARMRegisters::r0;
-
-        static const RegisterID regT0 = ARMRegisters::r0;
-        static const RegisterID regT1 = ARMRegisters::r1;
-        static const RegisterID regT2 = ARMRegisters::r2;
-        static const RegisterID regT3 = ARMRegisters::r4;
-
-        static const RegisterID callFrameRegister = ARMRegisters::r5;
-        static const RegisterID timeoutCheckRegister = ARMRegisters::r6;
-
-        static const FPRegisterID fpRegT0 = ARMRegisters::d0;
-        static const FPRegisterID fpRegT1 = ARMRegisters::d1;
-        static const FPRegisterID fpRegT2 = ARMRegisters::d2;
-#elif CPU(ARM_TRADITIONAL)
-        static const RegisterID returnValueRegister = ARMRegisters::r0;
-        static const RegisterID cachedResultRegister = ARMRegisters::r0;
-        static const RegisterID firstArgumentRegister = ARMRegisters::r0;
-
-        static const RegisterID timeoutCheckRegister = ARMRegisters::r5;
-        static const RegisterID callFrameRegister = ARMRegisters::r4;
-
-        static const RegisterID regT0 = ARMRegisters::r0;
-        static const RegisterID regT1 = ARMRegisters::r1;
-        static const RegisterID regT2 = ARMRegisters::r2;
-        // Callee preserved
-        static const RegisterID regT3 = ARMRegisters::r7;
-
-        static const RegisterID regS0 = ARMRegisters::S0;
-        // Callee preserved
-        static const RegisterID regS1 = ARMRegisters::S1;
-
-        static const RegisterID regStackPtr = ARMRegisters::sp;
-        static const RegisterID regLink = ARMRegisters::lr;
-
-        static const FPRegisterID fpRegT0 = ARMRegisters::d0;
-        static const FPRegisterID fpRegT1 = ARMRegisters::d1;
-        static const FPRegisterID fpRegT2 = ARMRegisters::d2;
-#else
-    #error "JIT not supported on this platform."
-#endif
-
         static const int patchGetByIdDefaultStructure = -1;
         // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler
         // will compress the displacement, and we may not be able to fit a patched offset.
         static const int patchGetByIdDefaultStructure = -1;
         // Magic number - initial offset cannot be representable as a signed 8bit value, or the X86Assembler
         // will compress the displacement, and we may not be able to fit a patched offset.
@@ -283,48 +183,50 @@ namespace JSC {
             return JIT(globalData, codeBlock).privateCompile();
         }
 
             return JIT(globalData, codeBlock).privateCompile();
         }
 
-        static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, ReturnAddressPtr returnAddress)
+        static void compileGetByIdProto(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress)
         {
             JIT jit(globalData, codeBlock);
         {
             JIT jit(globalData, codeBlock);
-            jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, cachedOffset, returnAddress, callFrame);
+            jit.privateCompileGetByIdProto(stubInfo, structure, prototypeStructure, ident, slot, cachedOffset, returnAddress, callFrame);
         }
 
         }
 
-        static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, size_t cachedOffset)
+        static void compileGetByIdSelfList(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
         {
             JIT jit(globalData, codeBlock);
         {
             JIT jit(globalData, codeBlock);
-            jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, cachedOffset);
+            jit.privateCompileGetByIdSelfList(stubInfo, polymorphicStructures, currentIndex, structure, ident, slot, cachedOffset);
         }
         }
-        static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset)
+        static void compileGetByIdProtoList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
         {
             JIT jit(globalData, codeBlock);
         {
             JIT jit(globalData, codeBlock);
-            jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, cachedOffset, callFrame);
+            jit.privateCompileGetByIdProtoList(stubInfo, prototypeStructureList, currentIndex, structure, prototypeStructure, ident, slot, cachedOffset, callFrame);
         }
         }
-        static void compileGetByIdChainList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset)
+        static void compileGetByIdChainList(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
         {
             JIT jit(globalData, codeBlock);
         {
             JIT jit(globalData, codeBlock);
-            jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, cachedOffset, callFrame);
+            jit.privateCompileGetByIdChainList(stubInfo, prototypeStructureList, currentIndex, structure, chain, count, ident, slot, cachedOffset, callFrame);
         }
 
         }
 
-        static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress)
+        static void compileGetByIdChain(JSGlobalData* globalData, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress)
         {
             JIT jit(globalData, codeBlock);
         {
             JIT jit(globalData, codeBlock);
-            jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, cachedOffset, returnAddress, callFrame);
+            jit.privateCompileGetByIdChain(stubInfo, structure, chain, count, ident, slot, cachedOffset, returnAddress, callFrame);
         }
         
         }
         
-        static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress)
+        static void compilePutByIdTransition(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
         {
             JIT jit(globalData, codeBlock);
         {
             JIT jit(globalData, codeBlock);
-            jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress);
+            jit.privateCompilePutByIdTransition(stubInfo, oldStructure, newStructure, cachedOffset, chain, returnAddress, direct);
         }
 
         }
 
-        static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
+        static void compileCTIMachineTrampolines(JSGlobalData* globalData, RefPtr<ExecutablePool>* executablePool, TrampolineStructure *trampolines)
         {
         {
+            if (!globalData->canUseJIT())
+                return;
             JIT jit(globalData);
             JIT jit(globalData);
-            jit.privateCompileCTIMachineTrampolines(executablePool, globalData, ctiStringLengthTrampoline, ctiVirtualCallLink, ctiVirtualCall, ctiNativeCallThunk);
+            jit.privateCompileCTIMachineTrampolines(executablePool, globalData, trampolines);
         }
 
         static void patchGetByIdSelf(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr 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 patchPutByIdReplace(CodeBlock* codeblock, StructureStubInfo*, Structure*, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct);
         static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr);
 
         static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
         static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr);
 
         static void compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
@@ -354,14 +256,14 @@ namespace JSC {
         void privateCompileLinkPass();
         void privateCompileSlowCases();
         JITCode privateCompile();
         void privateCompileLinkPass();
         void privateCompileSlowCases();
         JITCode privateCompile();
-        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);
-        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(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk);
+        void privateCompileGetByIdProto(StructureStubInfo*, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
+        void privateCompileGetByIdSelfList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, const Identifier&, const PropertySlot&, size_t cachedOffset);
+        void privateCompileGetByIdProtoList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, Structure* prototypeStructure, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
+        void privateCompileGetByIdChainList(StructureStubInfo*, PolymorphicAccessStructureList*, int, Structure*, StructureChain* chain, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, CallFrame* callFrame);
+        void privateCompileGetByIdChain(StructureStubInfo*, Structure*, StructureChain*, size_t count, const Identifier&, const PropertySlot&, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame);
+        void privateCompilePutByIdTransition(StructureStubInfo*, Structure*, Structure*, size_t cachedOffset, StructureChain*, ReturnAddressPtr returnAddress, bool direct);
+
+        void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, TrampolineStructure *trampolines);
         void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
 
         void addSlowCase(Jump);
         void privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress);
 
         void addSlowCase(Jump);
@@ -385,14 +287,9 @@ namespace JSC {
         void emitLoadDouble(unsigned index, FPRegisterID value);
         void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);
 
         void emitLoadDouble(unsigned index, FPRegisterID value);
         void emitLoadInt32ToDouble(unsigned index, FPRegisterID value);
 
-        Address addressFor(unsigned index, RegisterID base = callFrameRegister);
-
         void testPrototype(Structure*, JumpList& failureCases);
 
 #if USE(JSVALUE32_64)
         void testPrototype(Structure*, JumpList& failureCases);
 
 #if USE(JSVALUE32_64)
-        Address tagFor(unsigned index, RegisterID base = callFrameRegister);
-        Address payloadFor(unsigned index, RegisterID base = callFrameRegister);
-
         bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant);
 
         void emitLoadTag(unsigned index, RegisterID tag);
         bool getOperandConstantImmediateInt(unsigned op1, unsigned op2, unsigned& op, int32_t& constant);
 
         void emitLoadTag(unsigned index, RegisterID tag);
@@ -491,6 +388,47 @@ namespace JSC {
         static const int patchOffsetMethodCheckProtoStruct = 20;
         static const int patchOffsetMethodCheckPutFunction = 32;
 
         static const int patchOffsetMethodCheckProtoStruct = 20;
         static const int patchOffsetMethodCheckPutFunction = 32;
 
+        // sequenceOpCall
+        static const int sequenceOpCallInstructionSpace = 12;
+        static const int sequenceOpCallConstantSpace = 2;
+        // sequenceMethodCheck
+        static const int sequenceMethodCheckInstructionSpace = 40;
+        static const int sequenceMethodCheckConstantSpace = 6;
+        // sequenceGetByIdHotPath
+        static const int sequenceGetByIdHotPathInstructionSpace = 36;
+        static const int sequenceGetByIdHotPathConstantSpace = 4;
+        // sequenceGetByIdSlowCase
+        static const int sequenceGetByIdSlowCaseInstructionSpace = 40;
+        static const int sequenceGetByIdSlowCaseConstantSpace = 2;
+        // sequencePutById
+        static const int sequencePutByIdInstructionSpace = 36;
+        static const int sequencePutByIdConstantSpace = 4;
+#elif CPU(ARM_THUMB2)
+        // 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 = 26;
+        static const int patchLengthPutByIdExternalLoad = 12;
+        static const int patchOffsetPutByIdPropertyMapOffset1 = 46;
+        static const int patchOffsetPutByIdPropertyMapOffset2 = 58;
+        // 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 = 26;
+        static const int patchOffsetGetByIdExternalLoad = 26;
+        static const int patchLengthGetByIdExternalLoad = 12;
+        static const int patchOffsetGetByIdPropertyMapOffset1 = 46;
+        static const int patchOffsetGetByIdPropertyMapOffset2 = 58;
+        static const int patchOffsetGetByIdPutResult = 62;
+#if ENABLE(OPCODE_SAMPLING)
+        #error "OPCODE_SAMPLING is not yet supported"
+#else
+        static const int patchOffsetGetByIdSlowCaseCall = 30;
+#endif
+        static const int patchOffsetOpCallCompareToJump = 16;
+
+        static const int patchOffsetMethodCheckProtoObj = 24;
+        static const int patchOffsetMethodCheckProtoStruct = 34;
+        static const int patchOffsetMethodCheckPutFunction = 58;
+
         // sequenceOpCall
         static const int sequenceOpCallInstructionSpace = 12;
         static const int sequenceOpCallConstantSpace = 2;
         // sequenceOpCall
         static const int sequenceOpCallInstructionSpace = 12;
         static const int sequenceOpCallConstantSpace = 2;
@@ -529,8 +467,6 @@ namespace JSC {
         void emitJumpSlowCaseIfNotJSCell(RegisterID);
         void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
 #if USE(JSVALUE64)
         void emitJumpSlowCaseIfNotJSCell(RegisterID);
         void emitJumpSlowCaseIfNotJSCell(RegisterID, int VReg);
 #if USE(JSVALUE64)
-        JIT::Jump emitJumpIfImmediateNumber(RegisterID);
-        JIT::Jump emitJumpIfNotImmediateNumber(RegisterID);
 #else
         JIT::Jump emitJumpIfImmediateNumber(RegisterID reg)
         {
 #else
         JIT::Jump emitJumpIfImmediateNumber(RegisterID reg)
         {
@@ -554,7 +490,6 @@ namespace JSC {
         Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID);
 #endif
         void emitFastArithReTagImmediate(RegisterID src, RegisterID dest);
         Jump emitFastArithDeTagImmediateJumpIfZero(RegisterID);
 #endif
         void emitFastArithReTagImmediate(RegisterID src, RegisterID dest);
-        void emitFastArithImmToInt(RegisterID);
         void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);
 
         void emitTagAsBoolImmediate(RegisterID reg);
         void emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest);
 
         void emitTagAsBoolImmediate(RegisterID reg);
@@ -686,6 +621,48 @@ namespace JSC {
         // sequencePutById
         static const int sequencePutByIdInstructionSpace = 28;
         static const int sequencePutByIdConstantSpace = 3;
         // sequencePutById
         static const int sequencePutByIdInstructionSpace = 28;
         static const int sequencePutByIdConstantSpace = 3;
+#elif CPU(MIPS)
+#if WTF_MIPS_ISA(1)
+        static const int patchOffsetPutByIdStructure = 16;
+        static const int patchOffsetPutByIdExternalLoad = 48;
+        static const int patchLengthPutByIdExternalLoad = 20;
+        static const int patchOffsetPutByIdPropertyMapOffset = 68;
+        static const int patchOffsetGetByIdStructure = 16;
+        static const int patchOffsetGetByIdBranchToSlowCase = 48;
+        static const int patchOffsetGetByIdExternalLoad = 48;
+        static const int patchLengthGetByIdExternalLoad = 20;
+        static const int patchOffsetGetByIdPropertyMapOffset = 68;
+        static const int patchOffsetGetByIdPutResult = 88;
+#if ENABLE(OPCODE_SAMPLING)
+        #error "OPCODE_SAMPLING is not yet supported"
+#else
+        static const int patchOffsetGetByIdSlowCaseCall = 40;
+#endif
+        static const int patchOffsetOpCallCompareToJump = 32;
+        static const int patchOffsetMethodCheckProtoObj = 32;
+        static const int patchOffsetMethodCheckProtoStruct = 56;
+        static const int patchOffsetMethodCheckPutFunction = 88;
+#else // WTF_MIPS_ISA(1)
+        static const int patchOffsetPutByIdStructure = 12;
+        static const int patchOffsetPutByIdExternalLoad = 44;
+        static const int patchLengthPutByIdExternalLoad = 16;
+        static const int patchOffsetPutByIdPropertyMapOffset = 60;
+        static const int patchOffsetGetByIdStructure = 12;
+        static const int patchOffsetGetByIdBranchToSlowCase = 44;
+        static const int patchOffsetGetByIdExternalLoad = 44;
+        static const int patchLengthGetByIdExternalLoad = 16;
+        static const int patchOffsetGetByIdPropertyMapOffset = 60;
+        static const int patchOffsetGetByIdPutResult = 76;
+#if ENABLE(OPCODE_SAMPLING)
+        #error "OPCODE_SAMPLING is not yet supported"
+#else
+        static const int patchOffsetGetByIdSlowCaseCall = 40;
+#endif
+        static const int patchOffsetOpCallCompareToJump = 32;
+        static const int patchOffsetMethodCheckProtoObj = 32;
+        static const int patchOffsetMethodCheckProtoStruct = 52;
+        static const int patchOffsetMethodCheckPutFunction = 84;
+#endif
 #endif
 #endif // USE(JSVALUE32_64)
 
 #endif
 #endif // USE(JSVALUE32_64)
 
@@ -737,6 +714,7 @@ namespace JSC {
         void emit_op_jneq_ptr(Instruction*);
         void emit_op_jnless(Instruction*);
         void emit_op_jless(Instruction*);
         void emit_op_jneq_ptr(Instruction*);
         void emit_op_jnless(Instruction*);
         void emit_op_jless(Instruction*);
+        void emit_op_jlesseq(Instruction*, bool invert = false);
         void emit_op_jnlesseq(Instruction*);
         void emit_op_jsr(Instruction*);
         void emit_op_jtrue(Instruction*);
         void emit_op_jnlesseq(Instruction*);
         void emit_op_jsr(Instruction*);
         void emit_op_jtrue(Instruction*);
@@ -782,7 +760,8 @@ namespace JSC {
         void emit_op_put_setter(Instruction*);
         void emit_op_resolve(Instruction*);
         void emit_op_resolve_base(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_global(Instruction*, bool dynamic = false);
+        void emit_op_resolve_global_dynamic(Instruction*);
         void emit_op_resolve_skip(Instruction*);
         void emit_op_resolve_with_base(Instruction*);
         void emit_op_ret(Instruction*);
         void emit_op_resolve_skip(Instruction*);
         void emit_op_resolve_with_base(Instruction*);
         void emit_op_ret(Instruction*);
@@ -800,6 +779,10 @@ namespace JSC {
         void emit_op_to_jsnumber(Instruction*);
         void emit_op_to_primitive(Instruction*);
         void emit_op_unexpected_load(Instruction*);
         void emit_op_to_jsnumber(Instruction*);
         void emit_op_to_primitive(Instruction*);
         void emit_op_unexpected_load(Instruction*);
+        void emit_op_urshift(Instruction*);
+#if ENABLE(JIT_OPTIMIZE_MOD)
+        void softModulo();
+#endif
 
         void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
 
         void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -821,6 +804,7 @@ namespace JSC {
         void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_jfalse(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&);
+        void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&, bool invert = false);
         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_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_loop_if_less(Instruction*, Vector<SlowCaseEntry>::iterator&);
@@ -842,11 +826,17 @@ namespace JSC {
         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_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_resolve_global_dynamic(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&);
         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&);
+        void emitSlow_op_urshift(Instruction*, Vector<SlowCaseEntry>::iterator&);
+
+        
+        void emitRightShift(Instruction*, bool isUnsigned);
+        void emitRightShiftSlowCase(Instruction*, Vector<SlowCaseEntry>::iterator&, bool isUnsigned);
 
         /* These functions are deprecated: Please use JITStubCall instead. */
         void emitPutJITStubArg(RegisterID src, unsigned argumentNumber);
 
         /* These functions are deprecated: Please use JITStubCall instead. */
         void emitPutJITStubArg(RegisterID src, unsigned argumentNumber);
@@ -869,6 +859,7 @@ namespace JSC {
 
         JSValue getConstantOperand(unsigned src);
         bool isOperandConstantImmediateInt(unsigned src);
 
         JSValue getConstantOperand(unsigned src);
         bool isOperandConstantImmediateInt(unsigned src);
+        bool isOperandConstantImmediateChar(unsigned src);
 
         Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter)
         {
 
         Jump getSlowCase(Vector<SlowCaseEntry>::iterator& iter)
         {
@@ -892,6 +883,9 @@ namespace JSC {
         void restoreReturnAddressBeforeReturn(RegisterID);
         void restoreReturnAddressBeforeReturn(Address);
 
         void restoreReturnAddressBeforeReturn(RegisterID);
         void restoreReturnAddressBeforeReturn(Address);
 
+        // Loads the character value of a single character string into dst.
+        void emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures);
+        
         void emitTimeoutCheck();
 #ifndef NDEBUG
         void printBytecodeOperandTypes(unsigned src1, unsigned src2);
         void emitTimeoutCheck();
 #ifndef NDEBUG
         void printBytecodeOperandTypes(unsigned src1, unsigned src2);
@@ -953,6 +947,7 @@ namespace JSC {
         int m_uninterruptedConstantSequenceBegin;
 #endif
 #endif
         int m_uninterruptedConstantSequenceBegin;
 #endif
 #endif
+        static PassRefPtr<NativeExecutable> stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool);
     } JIT_CLASS_ALIGNMENT;
 
     inline void JIT::emit_op_loop(Instruction* currentInstruction)
     } JIT_CLASS_ALIGNMENT;
 
     inline void JIT::emit_op_loop(Instruction* currentInstruction)
index feee8d21b8aed47700f1187c9ed14f6a322742aa..cd39b3ad01c1ff45e15551efbbe01f0c12b633fc 100644 (file)
@@ -20,7 +20,7 @@
  * 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
  * 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. 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "config.h"
  */
 
 #include "config.h"
@@ -31,6 +31,7 @@
 #include "CodeBlock.h"
 #include "JITInlineMethods.h"
 #include "JITStubCall.h"
 #include "CodeBlock.h"
 #include "JITInlineMethods.h"
 #include "JITStubCall.h"
+#include "JITStubs.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "Interpreter.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "Interpreter.h"
@@ -45,1162 +46,7 @@ using namespace std;
 
 namespace JSC {
 
 
 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);
-    } 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);
-    } 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);
-    }
-
-    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);
-}
-
-void JIT::emit_op_jless(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(GreaterThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
-    } else if (isOperandConstantImmediateInt(op2)) {
-        emitLoad(op1, regT1, regT0);
-        notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
-        addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
-    } 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(LessThan, regT0, regT2), target);
-    }
-
-    if (!supportsFloatingPoint()) {
-        addSlowCase(notInt32Op1);
-        addSlowCase(notInt32Op2);
-        return;
-    }
-    Jump end = jump();
-
-    // Double less.
-    emitBinaryDoubleOp(op_jless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
-    end.link(this);
-}
-
-void JIT::emitSlow_op_jless(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(NonZero, regT0), target);
-}
-
-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);
-    } 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);
-    } 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);
-    }
-
-    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);
-}
-
-// 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);
-
-    if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
-        JITStubCall stubCall(this, cti_op_add);
-        stubCall.addArgument(op1);
-        stubCall.addArgument(op2);
-        stubCall.call(dst);
-        return;
-    }
-
-    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);
-
-    if (!types.first().mightBeNumber() || !types.second().mightBeNumber())
-        return;
-
-    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(DoubleLessThanOrEqualOrUnordered, fpRegT0, fpRegT2), dst);
-                break;
-            case op_jless:
-                emitLoadDouble(op1, fpRegT2);
-                addJump(branchDouble(DoubleLessThan, fpRegT2, fpRegT0), dst);
-                break;
-            case op_jnlesseq:
-                emitLoadDouble(op1, fpRegT2);
-                addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT0, fpRegT2), dst);
-                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(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), dst);
-                break;
-            case op_jless:
-                emitLoadDouble(op2, fpRegT1);
-                addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), dst);
-                break;
-            case op_jnlesseq:
-                emitLoadDouble(op2, fpRegT1);
-                addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), dst);
-                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;
-    branchConvertDoubleToInt32(fpRegT0, regT0, doubleResult, fpRegT1);
-
-    // 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 CPU(X86) || CPU(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, X86Registers::edx, X86Registers::eax);
-        move(Imm32(getConstantOperand(op2).asInt32()), X86Registers::ecx);
-        addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag)));
-        if (getConstantOperand(op2).asInt32() == -1)
-            addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
-    } else {
-        emitLoad2(op1, X86Registers::edx, X86Registers::eax, op2, X86Registers::ebx, X86Registers::ecx);
-        addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag)));
-        addSlowCase(branch32(NotEqual, X86Registers::ebx, Imm32(JSValue::Int32Tag)));
-
-        addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
-        addSlowCase(branch32(Equal, X86Registers::ecx, Imm32(0))); // divide by 0
-    }
-
-    move(X86Registers::eax, X86Registers::ebx); // Save dividend payload, in case of 0.
-    m_assembler.cdq();
-    m_assembler.idivl_r(X86Registers::ecx);
-    
-    // If the remainder is zero and the dividend is negative, the result is -0.
-    Jump storeResult1 = branchTest32(NonZero, X86Registers::edx);
-    Jump storeResult2 = branchTest32(Zero, X86Registers::ebx, Imm32(0x80000000)); // not negative
-    emitStore(dst, jsNumber(m_globalData, -0.0));
-    Jump end = jump();
-
-    storeResult1.link(this);
-    storeResult2.link(this);
-    emitStoreInt32(dst, X86Registers::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 // CPU(X86) || CPU(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 // CPU(X86) || CPU(X86_64)
-
-/* ------------------------------ END: OP_MOD ------------------------------ */
-
-#else // USE(JSVALUE32_64)
+#if !USE(JSVALUE32_64)
 
 void JIT::emit_op_lshift(Instruction* currentInstruction)
 {
 
 void JIT::emit_op_lshift(Instruction* currentInstruction)
 {
@@ -1341,6 +187,118 @@ void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEnt
     stubCall.call(result);
 }
 
     stubCall.call(result);
 }
 
+void JIT::emit_op_urshift(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    // Slow case of urshift makes assumptions about what registers hold the
+    // shift arguments, so any changes must be updated there as well.
+    if (isOperandConstantImmediateInt(op2)) {
+        emitGetVirtualRegister(op1, regT0);
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+        emitFastArithImmToInt(regT0);
+        int shift = getConstantOperand(op2).asInt32();
+        if (shift)
+            urshift32(Imm32(shift & 0x1f), regT0);
+        // unsigned shift < 0 or shift = k*2^32 may result in (essentially)
+        // a toUint conversion, which can result in a value we can represent
+        // as an immediate int.
+        if (shift < 0 || !(shift & 31))
+            addSlowCase(branch32(LessThan, regT0, Imm32(0)));
+#if USE(JSVALUE32)
+        addSlowCase(branchAdd32(Overflow, regT0, regT0));
+        signExtend32ToPtr(regT0, regT0);
+#endif
+        emitFastArithReTagImmediate(regT0, regT0);
+        emitPutVirtualRegister(dst, regT0);
+        return;
+    }
+    emitGetVirtualRegisters(op1, regT0, op2, regT1);
+    if (!isOperandConstantImmediateInt(op1))
+        emitJumpSlowCaseIfNotImmediateInteger(regT0);
+    emitJumpSlowCaseIfNotImmediateInteger(regT1);
+    emitFastArithImmToInt(regT0);
+    emitFastArithImmToInt(regT1);
+    urshift32(regT1, regT0);
+    addSlowCase(branch32(LessThan, regT0, Imm32(0)));
+#if USE(JSVALUE32)
+    addSlowCase(branchAdd32(Overflow, regT0, regT0));
+    signExtend32ToPtr(regT0, regT0);
+#endif
+    emitFastArithReTagImmediate(regT0, regT0);
+    emitPutVirtualRegister(dst, regT0);
+}
+
+void JIT::emitSlow_op_urshift(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)) {
+        int shift = getConstantOperand(op2).asInt32();
+        // op1 = regT0
+        linkSlowCase(iter); // int32 check
+#if USE(JSVALUE64)
+        if (supportsFloatingPointTruncate()) {
+            JumpList failures;
+            failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
+            addPtr(tagTypeNumberRegister, regT0);
+            movePtrToDouble(regT0, fpRegT0);
+            failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
+            if (shift)
+                urshift32(Imm32(shift & 0x1f), regT0);
+            if (shift < 0 || !(shift & 31))
+                failures.append(branch32(LessThan, regT0, Imm32(0)));
+            emitFastArithReTagImmediate(regT0, regT0);
+            emitPutVirtualRegister(dst, regT0);
+            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
+            failures.link(this);
+        }
+#endif // JSVALUE64
+        if (shift < 0 || !(shift & 31))
+            linkSlowCase(iter); // failed to box in hot path
+#if USE(JSVALUE32)
+        linkSlowCase(iter); // Couldn't box result
+#endif
+    } else {
+        // op1 = regT0
+        // op2 = regT1
+        if (!isOperandConstantImmediateInt(op1)) {
+            linkSlowCase(iter); // int32 check -- op1 is not an int
+#if USE(JSVALUE64)
+            if (supportsFloatingPointTruncate()) {
+                JumpList failures;
+                failures.append(emitJumpIfNotImmediateNumber(regT0)); // op1 is not a double
+                addPtr(tagTypeNumberRegister, regT0);
+                movePtrToDouble(regT0, fpRegT0);
+                failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
+                failures.append(emitJumpIfNotImmediateInteger(regT1)); // op2 is not an int
+                emitFastArithImmToInt(regT1);
+                urshift32(regT1, regT0);
+                failures.append(branch32(LessThan, regT0, Imm32(0)));
+                emitFastArithReTagImmediate(regT0, regT0);
+                emitPutVirtualRegister(dst, regT0);
+                emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
+                failures.link(this);
+            }
+#endif
+        }
+        
+        linkSlowCase(iter); // int32 check - op2 is not an int
+        linkSlowCase(iter); // Can't represent unsigned result as an immediate
+#if USE(JSVALUE32)
+        linkSlowCase(iter); // Couldn't box result
+#endif
+    }
+    
+    JITStubCall stubCall(this, cti_op_urshift);
+    stubCall.addArgument(op1, regT0);
+    stubCall.addArgument(op2, regT1);
+    stubCall.call(dst);
+}
+
 void JIT::emit_op_jnless(Instruction* currentInstruction)
 {
     unsigned op1 = currentInstruction[1].u.operand;
 void JIT::emit_op_jnless(Instruction* currentInstruction)
 {
     unsigned op1 = currentInstruction[1].u.operand;
@@ -1352,6 +310,24 @@ void JIT::emit_op_jnless(Instruction* currentInstruction)
     // - constant int immediate to int immediate
     // - int immediate to int immediate
 
     // - constant int immediate to int immediate
     // - int immediate to int immediate
 
+    if (isOperandConstantImmediateChar(op1)) {
+        emitGetVirtualRegister(op2, regT0);
+        addSlowCase(emitJumpIfNotJSCell(regT0));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
+        return;
+    }
+    if (isOperandConstantImmediateChar(op2)) {
+        emitGetVirtualRegister(op1, regT0);
+        addSlowCase(emitJumpIfNotJSCell(regT0));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
+        return;
+    }
     if (isOperandConstantImmediateInt(op2)) {
         emitGetVirtualRegister(op1, regT0);
         emitJumpSlowCaseIfNotImmediateInteger(regT0);
     if (isOperandConstantImmediateInt(op2)) {
         emitGetVirtualRegister(op1, regT0);
         emitJumpSlowCaseIfNotImmediateInteger(regT0);
@@ -1389,6 +365,18 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
     // - floating-point number to constant int immediate
     // - constant int immediate to floating-point number
     // - floating-point number to floating-point number.
     // - floating-point number to constant int immediate
     // - constant int immediate to floating-point number
     // - floating-point number to floating-point number.
+    if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_jless);
+        stubCall.addArgument(op1, regT0);
+        stubCall.addArgument(op2, regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(Zero, regT0), target);
+        return;
+    }
 
     if (isOperandConstantImmediateInt(op2)) {
         linkSlowCase(iter);
 
     if (isOperandConstantImmediateInt(op2)) {
         linkSlowCase(iter);
@@ -1406,9 +394,9 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
             Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
             loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
 #endif
             Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
             loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
 #endif
-            
+
             int32_t op2imm = getConstantOperand(op2).asInt32();;
             int32_t op2imm = getConstantOperand(op2).asInt32();;
-                    
+
             move(Imm32(op2imm), regT1);
             convertInt32ToDouble(regT1, fpRegT1);
 
             move(Imm32(op2imm), regT1);
             convertInt32ToDouble(regT1, fpRegT1);
 
@@ -1443,13 +431,13 @@ void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEnt
             Jump fail1;
             if (!m_codeBlock->isKnownNotImmediate(op2))
                 fail1 = emitJumpIfNotJSCell(regT1);
             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
             Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
             loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
-            
+
             int32_t op1imm = getConstantOperand(op1).asInt32();;
             int32_t op1imm = getConstantOperand(op1).asInt32();;
-                    
+
             move(Imm32(op1imm), regT0);
             convertInt32ToDouble(regT0, fpRegT0);
 
             move(Imm32(op1imm), regT0);
             convertInt32ToDouble(regT0, fpRegT0);
 
@@ -1537,6 +525,24 @@ void JIT::emit_op_jless(Instruction* currentInstruction)
     // - constant int immediate to int immediate
     // - int immediate to int immediate
 
     // - constant int immediate to int immediate
     // - int immediate to int immediate
 
+    if (isOperandConstantImmediateChar(op1)) {
+        emitGetVirtualRegister(op2, regT0);
+        addSlowCase(emitJumpIfNotJSCell(regT0));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(GreaterThan, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
+        return;
+    }
+    if (isOperandConstantImmediateChar(op2)) {
+        emitGetVirtualRegister(op1, regT0);
+        addSlowCase(emitJumpIfNotJSCell(regT0));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(LessThan, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
+        return;
+    }
     if (isOperandConstantImmediateInt(op2)) {
         emitGetVirtualRegister(op1, regT0);
         emitJumpSlowCaseIfNotImmediateInteger(regT0);
     if (isOperandConstantImmediateInt(op2)) {
         emitGetVirtualRegister(op1, regT0);
         emitJumpSlowCaseIfNotImmediateInteger(regT0);
@@ -1574,6 +580,18 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
     // - floating-point number to constant int immediate
     // - constant int immediate to floating-point number
     // - floating-point number to floating-point number.
     // - floating-point number to constant int immediate
     // - constant int immediate to floating-point number
     // - floating-point number to floating-point number.
+    if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_jless);
+        stubCall.addArgument(op1, regT0);
+        stubCall.addArgument(op2, regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
+        return;
+    }
 
     if (isOperandConstantImmediateInt(op2)) {
         linkSlowCase(iter);
 
     if (isOperandConstantImmediateInt(op2)) {
         linkSlowCase(iter);
@@ -1591,9 +609,9 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
             Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
             loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
 #endif
             Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
             loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
 #endif
-            
+
             int32_t op2imm = getConstantOperand(op2).asInt32();
             int32_t op2imm = getConstantOperand(op2).asInt32();
-                    
+
             move(Imm32(op2imm), regT1);
             convertInt32ToDouble(regT1, fpRegT1);
 
             move(Imm32(op2imm), regT1);
             convertInt32ToDouble(regT1, fpRegT1);
 
@@ -1628,13 +646,13 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
             Jump fail1;
             if (!m_codeBlock->isKnownNotImmediate(op2))
                 fail1 = emitJumpIfNotJSCell(regT1);
             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
             Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
             loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
-            
+
             int32_t op1imm = getConstantOperand(op1).asInt32();
             int32_t op1imm = getConstantOperand(op1).asInt32();
-                    
+
             move(Imm32(op1imm), regT0);
             convertInt32ToDouble(regT0, fpRegT0);
 
             move(Imm32(op1imm), regT0);
             convertInt32ToDouble(regT0, fpRegT0);
 
@@ -1711,7 +729,7 @@ void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntr
     }
 }
 
     }
 }
 
-void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
+void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
 {
     unsigned op1 = currentInstruction[1].u.operand;
     unsigned op2 = currentInstruction[2].u.operand;
 {
     unsigned op1 = currentInstruction[1].u.operand;
     unsigned op2 = currentInstruction[2].u.operand;
@@ -1722,6 +740,24 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
     // - constant int immediate to int immediate
     // - int immediate to int immediate
 
     // - constant int immediate to int immediate
     // - int immediate to int immediate
 
+    if (isOperandConstantImmediateChar(op1)) {
+        emitGetVirtualRegister(op2, regT0);
+        addSlowCase(emitJumpIfNotJSCell(regT0));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
+        return;
+    }
+    if (isOperandConstantImmediateChar(op2)) {
+        emitGetVirtualRegister(op1, regT0);
+        addSlowCase(emitJumpIfNotJSCell(regT0));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
+        return;
+    }
     if (isOperandConstantImmediateInt(op2)) {
         emitGetVirtualRegister(op1, regT0);
         emitJumpSlowCaseIfNotImmediateInteger(regT0);
     if (isOperandConstantImmediateInt(op2)) {
         emitGetVirtualRegister(op1, regT0);
         emitJumpSlowCaseIfNotImmediateInteger(regT0);
@@ -1730,7 +766,7 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
 #else
         int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
 #endif
 #else
         int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
 #endif
-        addJump(branch32(GreaterThan, regT0, Imm32(op2imm)), target);
+        addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(op2imm)), target);
     } else if (isOperandConstantImmediateInt(op1)) {
         emitGetVirtualRegister(op2, regT1);
         emitJumpSlowCaseIfNotImmediateInteger(regT1);
     } else if (isOperandConstantImmediateInt(op1)) {
         emitGetVirtualRegister(op2, regT1);
         emitJumpSlowCaseIfNotImmediateInteger(regT1);
@@ -1739,17 +775,17 @@ void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
 #else
         int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
 #endif
 #else
         int32_t op1imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op1)));
 #endif
-        addJump(branch32(LessThan, regT1, Imm32(op1imm)), target);
+        addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT1, Imm32(op1imm)), target);
     } else {
         emitGetVirtualRegisters(op1, regT0, op2, regT1);
         emitJumpSlowCaseIfNotImmediateInteger(regT0);
         emitJumpSlowCaseIfNotImmediateInteger(regT1);
 
     } else {
         emitGetVirtualRegisters(op1, regT0, op2, regT1);
         emitJumpSlowCaseIfNotImmediateInteger(regT0);
         emitJumpSlowCaseIfNotImmediateInteger(regT1);
 
-        addJump(branch32(GreaterThan, regT0, regT1), target);
+        addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, regT1), target);
     }
 }
 
     }
 }
 
-void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool invert)
 {
     unsigned op1 = currentInstruction[1].u.operand;
     unsigned op2 = currentInstruction[2].u.operand;
 {
     unsigned op1 = currentInstruction[1].u.operand;
     unsigned op2 = currentInstruction[2].u.operand;
@@ -1760,6 +796,19 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
     // - constant int immediate to floating-point number
     // - floating-point number to floating-point number.
 
     // - constant int immediate to floating-point number
     // - floating-point number to floating-point number.
 
+    if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        JITStubCall stubCall(this, cti_op_jlesseq);
+        stubCall.addArgument(op1, regT0);
+        stubCall.addArgument(op2, regT1);
+        stubCall.call();
+        emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
+        return;
+    }
+
     if (isOperandConstantImmediateInt(op2)) {
         linkSlowCase(iter);
 
     if (isOperandConstantImmediateInt(op2)) {
         linkSlowCase(iter);
 
@@ -1776,13 +825,13 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
             Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
             loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
 #endif
             Jump fail2 = checkStructure(regT0, m_globalData->numberStructure.get());
             loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
 #endif
-            
+
             int32_t op2imm = getConstantOperand(op2).asInt32();;
             int32_t op2imm = getConstantOperand(op2).asInt32();;
-                    
+
             move(Imm32(op2imm), regT1);
             convertInt32ToDouble(regT1, fpRegT1);
 
             move(Imm32(op2imm), regT1);
             convertInt32ToDouble(regT1, fpRegT1);
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
@@ -1799,7 +848,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
         stubCall.addArgument(regT0);
         stubCall.addArgument(op2, regT2);
         stubCall.call();
         stubCall.addArgument(regT0);
         stubCall.addArgument(op2, regT2);
         stubCall.call();
-        emitJumpSlowToHot(branchTest32(Zero, regT0), target);
+        emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
 
     } else if (isOperandConstantImmediateInt(op1)) {
         linkSlowCase(iter);
 
     } else if (isOperandConstantImmediateInt(op1)) {
         linkSlowCase(iter);
@@ -1813,17 +862,17 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
             Jump fail1;
             if (!m_codeBlock->isKnownNotImmediate(op2))
                 fail1 = emitJumpIfNotJSCell(regT1);
             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
             Jump fail2 = checkStructure(regT1, m_globalData->numberStructure.get());
             loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
-            
+
             int32_t op1imm = getConstantOperand(op1).asInt32();;
             int32_t op1imm = getConstantOperand(op1).asInt32();;
-                    
+
             move(Imm32(op1imm), regT0);
             convertInt32ToDouble(regT0, fpRegT0);
 
             move(Imm32(op1imm), regT0);
             convertInt32ToDouble(regT0, fpRegT0);
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
@@ -1840,7 +889,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
         stubCall.addArgument(op1, regT2);
         stubCall.addArgument(regT1);
         stubCall.call();
         stubCall.addArgument(op1, regT2);
         stubCall.addArgument(regT1);
         stubCall.call();
-        emitJumpSlowToHot(branchTest32(Zero, regT0), target);
+        emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
 
     } else {
         linkSlowCase(iter);
 
     } else {
         linkSlowCase(iter);
@@ -1869,7 +918,7 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
             loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
 
             loadDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT1);
 #endif
 
-            emitJumpSlowToHot(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), target);
+            emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target);
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
 
             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
 
@@ -1892,10 +941,20 @@ void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseE
         stubCall.addArgument(regT0);
         stubCall.addArgument(regT1);
         stubCall.call();
         stubCall.addArgument(regT0);
         stubCall.addArgument(regT1);
         stubCall.call();
-        emitJumpSlowToHot(branchTest32(Zero, regT0), target);
+        emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
     }
 }
 
     }
 }
 
+void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
+{
+    emit_op_jlesseq(currentInstruction, true);
+}
+
+void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    emitSlow_op_jlesseq(currentInstruction, iter, true);
+}
+
 void JIT::emit_op_bitand(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
 void JIT::emit_op_bitand(Instruction* currentInstruction)
 {
     unsigned result = currentInstruction[1].u.operand;
@@ -2138,15 +1197,40 @@ void JIT::emit_op_mod(Instruction* currentInstruction)
     unsigned op1 = currentInstruction[2].u.operand;
     unsigned op2 = currentInstruction[3].u.operand;
 
     unsigned op1 = currentInstruction[2].u.operand;
     unsigned op2 = currentInstruction[3].u.operand;
 
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    emitGetVirtualRegisters(op1, regT0, op2, regT2);
+    emitJumpSlowCaseIfNotImmediateInteger(regT0);
+    emitJumpSlowCaseIfNotImmediateInteger(regT2);
+
+    addSlowCase(branch32(Equal, regT2, Imm32(1)));
+
+    emitNakedCall(m_globalData->jitStubs.ctiSoftModulo());
+
+    emitPutVirtualRegister(result, regT0);
+#else
     JITStubCall stubCall(this, cti_op_mod);
     stubCall.addArgument(op1, regT2);
     stubCall.addArgument(op2, regT2);
     stubCall.call(result);
     JITStubCall stubCall(this, cti_op_mod);
     stubCall.addArgument(op1, regT2);
     stubCall.addArgument(op2, regT2);
     stubCall.call(result);
+#endif
 }
 
 }
 
-void JIT::emitSlow_op_mod(Instruction*, Vector<SlowCaseEntry>::iterator&)
+void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
 {
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(op1, regT2);
+    stubCall.addArgument(op2, regT2);
+    stubCall.call(result);
+#else
     ASSERT_NOT_REACHED();
     ASSERT_NOT_REACHED();
+#endif
 }
 
 #endif // CPU(X86) || CPU(X86_64)
 }
 
 #endif // CPU(X86) || CPU(X86_64)
@@ -2178,7 +1262,7 @@ void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>:
 {
     // We assume that subtracting TagTypeNumber is equivalent to adding DoubleEncodeOffset.
     COMPILE_ASSERT(((JSImmediate::TagTypeNumber + JSImmediate::DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0);
 {
     // We assume that subtracting TagTypeNumber is equivalent to adding DoubleEncodeOffset.
     COMPILE_ASSERT(((JSImmediate::TagTypeNumber + JSImmediate::DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0);
-    
+
     Jump notImm1;
     Jump notImm2;
     if (op1HasImmediateIntFastCase) {
     Jump notImm1;
     Jump notImm2;
     if (op1HasImmediateIntFastCase) {
@@ -2371,7 +1455,7 @@ void JIT::emit_op_div(Instruction* currentInstruction)
         movePtrToDouble(regT0, fpRegT0);
         skipDoubleLoad.link(this);
     }
         movePtrToDouble(regT0, fpRegT0);
         skipDoubleLoad.link(this);
     }
-    
+
     if (isOperandConstantImmediateDouble(op2)) {
         emitGetVirtualRegister(op2, regT1);
         addPtr(tagTypeNumberRegister, regT1);
     if (isOperandConstantImmediateDouble(op2)) {
         emitGetVirtualRegister(op2, regT1);
         addPtr(tagTypeNumberRegister, regT1);
@@ -2484,7 +1568,7 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
         op1imm.link(this);
         emitFastArithImmToInt(regT0);
         convertInt32ToDouble(regT0, fpRegT0);
         op1imm.link(this);
         emitFastArithImmToInt(regT0);
         convertInt32ToDouble(regT0, fpRegT0);
-        // (1c) 
+        // (1c)
         loadedDouble.link(this);
         if (opcodeID == op_add)
             addDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
         loadedDouble.link(this);
         if (opcodeID == op_add)
             addDouble(Address(regT1, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
@@ -2530,7 +1614,7 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
         op2imm.link(this);
         emitFastArithImmToInt(regT1);
         convertInt32ToDouble(regT1, fpRegT1);
         op2imm.link(this);
         emitFastArithImmToInt(regT1);
         convertInt32ToDouble(regT1, fpRegT1);
-        // (1c) 
+        // (1c)
         loadedDouble.link(this);
         loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
         if (opcodeID == op_add)
         loadedDouble.link(this);
         loadDouble(Address(regT0, OBJECT_OFFSETOF(JSNumberCell, m_value)), fpRegT0);
         if (opcodeID == op_add)
@@ -2571,7 +1655,7 @@ void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, u
         Jump op2NonZero = branchTest32(NonZero, regT1);
         op1Zero.link(this);
         // if either input is zero, add the two together, and check if the result is < 0.
         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. 
+        // If it is, we have a problem (N < 0), (N * 0) == -0, not representatble as a JSImmediate.
         move(regT0, regT2);
         addSlowCase(branchAdd32(Signed, regT1, regT2));
         // Skip the above check if neither input is zero
         move(regT0, regT2);
         addSlowCase(branchAdd32(Signed, regT1, regT2));
         // Skip the above check if neither input is zero
@@ -2750,7 +1834,7 @@ void JIT::emitSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>
 
 /* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */
 
 
 /* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */
 
-#endif // USE(JSVALUE32_64)
+#endif // !USE(JSVALUE32_64)
 
 } // namespace JSC
 
 
 } // namespace JSC
 
diff --git a/jit/JITArithmetic32_64.cpp b/jit/JITArithmetic32_64.cpp
new file mode 100644 (file)
index 0000000..3e5adc9
--- /dev/null
@@ -0,0 +1,1413 @@
+/*
+* 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 "JIT.h"
+
+#if ENABLE(JIT)
+
+#include "CodeBlock.h"
+#include "JITInlineMethods.h"
+#include "JITStubCall.h"
+#include "JITStubs.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "Interpreter.h"
+#include "ResultType.h"
+#include "SamplingTool.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+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(branchTest32(Zero, regT0, Imm32(0x7fffffff)));
+    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); // 0x7fffffff 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;
+
+    // Character less.
+    if (isOperandConstantImmediateChar(op1)) {
+        emitLoad(op2, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
+        return;
+    }
+    if (isOperandConstantImmediateChar(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
+        return;
+    }
+    if (isOperandConstantImmediateInt(op1)) {
+        // Int32 less.
+        emitLoad(op2, regT3, regT2);
+        notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
+    } 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);
+    } 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);
+    }
+
+    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 (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+    } else {
+        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);
+}
+
+void JIT::emit_op_jless(Instruction* currentInstruction)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    JumpList notInt32Op1;
+    JumpList notInt32Op2;
+
+    // Character less.
+    if (isOperandConstantImmediateChar(op1)) {
+        emitLoad(op2, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(GreaterThan, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
+        return;
+    }
+    if (isOperandConstantImmediateChar(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(LessThan, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
+        return;
+    } 
+    if (isOperandConstantImmediateInt(op1)) {
+        emitLoad(op2, regT3, regT2);
+        notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(GreaterThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
+    } else if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
+    } 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(LessThan, regT0, regT2), target);
+    }
+
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32Op1);
+        addSlowCase(notInt32Op2);
+        return;
+    }
+    Jump end = jump();
+
+    // Double less.
+    emitBinaryDoubleOp(op_jless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
+    end.link(this);
+}
+
+void JIT::emitSlow_op_jless(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 (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+    } else {
+        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(NonZero, regT0), target);
+}
+
+void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    JumpList notInt32Op1;
+    JumpList notInt32Op2;
+
+    // Character less.
+    if (isOperandConstantImmediateChar(op1)) {
+        emitLoad(op2, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
+        return;
+    }
+    if (isOperandConstantImmediateChar(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+        JumpList failures;
+        emitLoadCharacterString(regT0, regT0, failures);
+        addSlowCase(failures);
+        addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
+        return;
+    }
+    if (isOperandConstantImmediateInt(op1)) {
+        emitLoad(op2, regT3, regT2);
+        notInt32Op2.append(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
+    } else if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        notInt32Op1.append(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
+    } 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(invert ? GreaterThan : LessThanOrEqual, regT0, regT2), target);
+    }
+
+    if (!supportsFloatingPoint()) {
+        addSlowCase(notInt32Op1);
+        addSlowCase(notInt32Op2);
+        return;
+    }
+    Jump end = jump();
+
+    // Double less.
+    emitBinaryDoubleOp(invert ? op_jnlesseq : op_jlesseq, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
+    end.link(this);
+}
+
+void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool invert)
+{
+    unsigned op1 = currentInstruction[1].u.operand;
+    unsigned op2 = currentInstruction[2].u.operand;
+    unsigned target = currentInstruction[3].u.operand;
+
+    if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+        linkSlowCase(iter);
+    } else {
+        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(invert ? Zero : NonZero, regT0), target);
+}
+
+void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
+{
+    emit_op_jlesseq(currentInstruction, true);
+}
+
+void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    emitSlow_op_jlesseq(currentInstruction, iter, true);
+}
+
+// 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 (>>) and UnsignedRightShift (>>>) helper
+
+void JIT::emitRightShift(Instruction* currentInstruction, bool isUnsigned)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+
+    // Slow case of rshift makes assumptions about what registers hold the
+    // shift arguments, so any changes must be updated there as well.
+    if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        int shift = getConstantOperand(op2).asInt32();
+        if (isUnsigned) {
+            if (shift)
+                urshift32(Imm32(shift & 0x1f), regT0);
+            // unsigned shift < 0 or shift = k*2^32 may result in (essentially)
+            // a toUint conversion, which can result in a value we can represent
+            // as an immediate int.
+            if (shift < 0 || !(shift & 31))
+                addSlowCase(branch32(LessThan, regT0, Imm32(0)));
+        } else if (shift) { // signed right shift by zero is simply toInt conversion
+            rshift32(Imm32(shift & 0x1f), 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)));
+    if (isUnsigned) {
+        urshift32(regT2, regT0);
+        addSlowCase(branch32(LessThan, regT0, Imm32(0)));
+    } else
+        rshift32(regT2, regT0);
+    emitStoreInt32(dst, regT0, dst == op1 || dst == op2);
+}
+
+void JIT::emitRightShiftSlowCase(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool isUnsigned)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    if (isOperandConstantImmediateInt(op2)) {
+        int shift = getConstantOperand(op2).asInt32();
+        // op1 = regT1:regT0
+        linkSlowCase(iter); // int32 check
+        if (supportsFloatingPointTruncate()) {
+            JumpList failures;
+            failures.append(branch32(AboveOrEqual, regT1, Imm32(JSValue::LowestTag)));
+            emitLoadDouble(op1, fpRegT0);
+            failures.append(branchTruncateDoubleToInt32(fpRegT0, regT0));
+            if (isUnsigned) {
+                if (shift)
+                    urshift32(Imm32(shift & 0x1f), regT0);
+                if (shift < 0 || !(shift & 31))
+                    failures.append(branch32(LessThan, regT0, Imm32(0)));
+            } else if (shift)
+                rshift32(Imm32(shift & 0x1f), regT0);
+            emitStoreInt32(dst, regT0, false);
+            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
+            failures.link(this);
+        }
+        if (isUnsigned && (shift < 0 || !(shift & 31)))
+            linkSlowCase(iter); // failed to box in hot path
+    } else {
+        // op1 = regT1:regT0
+        // op2 = regT3:regT2
+        if (!isOperandConstantImmediateInt(op1)) {
+            linkSlowCase(iter); // int32 check -- op1 is not an int
+            if (supportsFloatingPointTruncate()) {
+                Jump notDouble = branch32(Above, regT1, Imm32(JSValue::LowestTag)); // op1 is not a double
+                emitLoadDouble(op1, fpRegT0);
+                Jump notInt = branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)); // op2 is not an int
+                Jump cantTruncate = branchTruncateDoubleToInt32(fpRegT0, regT0);
+                if (isUnsigned)
+                    urshift32(regT2, regT0);
+                else
+                    rshift32(regT2, regT0);
+                emitStoreInt32(dst, regT0, false);
+                emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_rshift));
+                notDouble.link(this);
+                notInt.link(this);
+                cantTruncate.link(this);
+            }
+        }
+
+        linkSlowCase(iter); // int32 check - op2 is not an int
+        if (isUnsigned)
+            linkSlowCase(iter); // Can't represent unsigned result as an immediate
+    }
+
+    JITStubCall stubCall(this, isUnsigned ? cti_op_urshift : cti_op_rshift);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+}
+
+// RightShift (>>)
+
+void JIT::emit_op_rshift(Instruction* currentInstruction)
+{
+    emitRightShift(currentInstruction, false);
+}
+
+void JIT::emitSlow_op_rshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    emitRightShiftSlowCase(currentInstruction, iter, false);
+}
+
+// UnsignedRightShift (>>>)
+
+void JIT::emit_op_urshift(Instruction* currentInstruction)
+{
+    emitRightShift(currentInstruction, true);
+}
+
+void JIT::emitSlow_op_urshift(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    emitRightShiftSlowCase(currentInstruction, iter, true);
+}
+
+// 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);
+
+    if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
+        JITStubCall stubCall(this, cti_op_add);
+        stubCall.addArgument(op1);
+        stubCall.addArgument(op2);
+        stubCall.call(dst);
+        return;
+    }
+
+    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);
+
+    if (!types.first().mightBeNumber() || !types.second().mightBeNumber())
+        return;
+
+    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(DoubleLessThanOrEqualOrUnordered, fpRegT0, fpRegT2), dst);
+                break;
+            case op_jless:
+                emitLoadDouble(op1, fpRegT2);
+                addJump(branchDouble(DoubleLessThan, fpRegT2, fpRegT0), dst);
+                break;
+            case op_jlesseq:
+                emitLoadDouble(op1, fpRegT2);
+                addJump(branchDouble(DoubleLessThanOrEqual, fpRegT2, fpRegT0), dst);
+                break;
+            case op_jnlesseq:
+                emitLoadDouble(op1, fpRegT2);
+                addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT0, fpRegT2), dst);
+                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(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), dst);
+                break;
+            case op_jless:
+                emitLoadDouble(op2, fpRegT1);
+                addJump(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), dst);
+                break;
+            case op_jnlesseq:
+                emitLoadDouble(op2, fpRegT1);
+                addJump(branchDouble(DoubleLessThanOrUnordered, fpRegT1, fpRegT0), dst);
+                break;
+            case op_jlesseq:
+                emitLoadDouble(op2, fpRegT1);
+                addJump(branchDouble(DoubleLessThanOrEqual, fpRegT0, fpRegT1), dst);
+                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;
+    branchConvertDoubleToInt32(fpRegT0, regT0, doubleResult, fpRegT1);
+
+    // 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 CPU(X86) || CPU(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, X86Registers::edx, X86Registers::eax);
+        move(Imm32(getConstantOperand(op2).asInt32()), X86Registers::ecx);
+        addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag)));
+        if (getConstantOperand(op2).asInt32() == -1)
+            addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
+    } else {
+        emitLoad2(op1, X86Registers::edx, X86Registers::eax, op2, X86Registers::ebx, X86Registers::ecx);
+        addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag)));
+        addSlowCase(branch32(NotEqual, X86Registers::ebx, Imm32(JSValue::Int32Tag)));
+
+        addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
+        addSlowCase(branch32(Equal, X86Registers::ecx, Imm32(0))); // divide by 0
+    }
+
+    move(X86Registers::eax, X86Registers::ebx); // Save dividend payload, in case of 0.
+    m_assembler.cdq();
+    m_assembler.idivl_r(X86Registers::ecx);
+
+    // If the remainder is zero and the dividend is negative, the result is -0.
+    Jump storeResult1 = branchTest32(NonZero, X86Registers::edx);
+    Jump storeResult2 = branchTest32(Zero, X86Registers::ebx, Imm32(0x80000000)); // not negative
+    emitStore(dst, jsNumber(m_globalData, -0.0));
+    Jump end = jump();
+
+    storeResult1.link(this);
+    storeResult2.link(this);
+    emitStoreInt32(dst, X86Registers::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 // CPU(X86) || CPU(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 ENABLE(JIT_OPTIMIZE_MOD)
+    emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
+    addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+    addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));
+
+    addSlowCase(branch32(Equal, regT2, Imm32(0)));
+
+    emitNakedCall(m_globalData->jitStubs.ctiSoftModulo());
+
+    emitStoreInt32(dst, regT0, (op1 == dst || op2 == dst));
+#else
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(dst);
+#endif
+}
+
+void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    unsigned result = currentInstruction[1].u.operand;
+    unsigned op1 = currentInstruction[2].u.operand;
+    unsigned op2 = currentInstruction[3].u.operand;
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    JITStubCall stubCall(this, cti_op_mod);
+    stubCall.addArgument(op1);
+    stubCall.addArgument(op2);
+    stubCall.call(result);
+#else
+    UNUSED_PARAM(currentInstruction);
+    UNUSED_PARAM(iter);
+    ASSERT_NOT_REACHED();
+#endif
+}
+
+#endif // CPU(X86) || CPU(X86_64)
+
+/* ------------------------------ END: OP_MOD ------------------------------ */
+
+#endif // USE(JSVALUE32_64)
+
+}
+
+#endif // ENABLE(JIT)
index 179aad769a749f6fd02e3f20bf10a583f52e1429..625b40dbdf1dcafabdf0e51a143d4fb558684c09 100644 (file)
@@ -114,7 +114,7 @@ void JIT::compileOpCallVarargs(Instruction* instruction)
 
     move(regT2, regT1); // argCount
 
 
     move(regT2, regT1); // argCount
 
-    emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
+    emitNakedCall(m_globalData->jitStubs->ctiVirtualCall());
 
     emitStore(dst, regT1, regT0);
     
 
     emitStore(dst, regT1, regT0);
     
@@ -159,7 +159,7 @@ void JIT::emit_op_construct_verify(Instruction* currentInstruction)
     emitLoad(dst, regT1, regT0);
     addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
     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)));
+    addSlowCase(branch8(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)
 }
 
 void JIT::emitSlow_op_construct_verify(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
@@ -400,7 +400,7 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
     addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
     move(Imm32(argCount), regT1);
 
     addPtr(Imm32(registerOffset * static_cast<int>(sizeof(Register))), callFrameRegister);
     move(Imm32(argCount), regT1);
 
-    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallLink());
+    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs->ctiVirtualCallLink());
 
     // Put the return value in dst.
     emitStore(dst, regT1, regT0);;
 
     // Put the return value in dst.
     emitStore(dst, regT1, regT0);;
@@ -499,7 +499,7 @@ void JIT::compileOpCallVarargs(Instruction* instruction)
     addPtr(callFrameRegister, regT3);
     storePtr(callFrameRegister, regT3);
     addPtr(regT2, callFrameRegister);
     addPtr(callFrameRegister, regT3);
     storePtr(callFrameRegister, regT3);
     addPtr(regT2, callFrameRegister);
-    emitNakedCall(m_globalData->jitStubs.ctiVirtualCall());
+    emitNakedCall(m_globalData->jitStubs->ctiVirtualCall());
 
     // Put the return value in dst. In the interpreter, op_ret does this.
     emitPutVirtualRegister(dst);
 
     // Put the return value in dst. In the interpreter, op_ret does this.
     emitPutVirtualRegister(dst);
@@ -691,7 +691,7 @@ void JIT::compileOpCallSlowCase(Instruction* instruction, Vector<SlowCaseEntry>:
 
     move(regT0, regT2);
 
 
     move(regT0, regT2);
 
-    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs.ctiVirtualCallLink());
+    m_callStructureStubCompilationInfo[callLinkInfoIndex].callReturnLocation = emitNakedCall(m_globalData->jitStubs->ctiVirtualCallLink());
 
     // Put the return value in dst.
     emitPutVirtualRegister(dst);
 
     // Put the return value in dst.
     emitPutVirtualRegister(dst);
index 69cf16728e22c6104c81057f96be053b6ef485fe..5d889b52f9ac42f7a891803ec6bbe4b388636904 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef JITCode_h
 #define JITCode_h
 
 #ifndef JITCode_h
 #define JITCode_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(JIT)
 
 #include "CallFrame.h"
 #if ENABLE(JIT)
 
 #include "CallFrame.h"
index 5af756529d68f8573adb586373e21102a1031172..824ca4b0341a8f579a4b847e3e27e50b69787bab 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef JITInlineMethods_h
 #define JITInlineMethods_h
 
 #ifndef JITInlineMethods_h
 #define JITInlineMethods_h
 
-#include <wtf/Platform.h>
 
 #if ENABLE(JIT)
 
 
 #if ENABLE(JIT)
 
@@ -94,6 +93,16 @@ ALWAYS_INLINE void JIT::emitGetFromCallFrameHeaderPtr(RegisterFile::CallFrameHea
 #endif
 }
 
 #endif
 }
 
+ALWAYS_INLINE void JIT::emitLoadCharacterString(RegisterID src, RegisterID dst, JumpList& failures)
+{
+    failures.append(branchPtr(NotEqual, Address(src), ImmPtr(m_globalData->jsStringVPtr)));
+    failures.append(branchTest32(NonZero, Address(src, OBJECT_OFFSETOF(JSString, m_fiberCount))));
+    failures.append(branch32(NotEqual, MacroAssembler::Address(src, ThunkHelpers::jsStringLengthOffset()), Imm32(1)));
+    loadPtr(MacroAssembler::Address(src, ThunkHelpers::jsStringValueOffset()), dst);
+    loadPtr(MacroAssembler::Address(dst, ThunkHelpers::stringImplDataOffset()), dst);
+    load16(MacroAssembler::Address(dst, 0), dst);
+}
+
 ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
 {
     load32(Address(from, entry * sizeof(Register)), to);
 ALWAYS_INLINE void JIT::emitGetFromCallFrameHeader32(RegisterFile::CallFrameHeaderEntry entry, RegisterID to, RegisterID from)
 {
     load32(Address(from, entry * sizeof(Register)), to);
@@ -161,6 +170,23 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
     loadPtr(address, linkRegister);
 }
 
     loadPtr(address, linkRegister);
 }
 
+#elif CPU(MIPS)
+
+ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
+{
+    move(returnAddressRegister, reg);
+}
+
+ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(RegisterID reg)
+{
+    move(reg, returnAddressRegister);
+}
+
+ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
+{
+    loadPtr(address, returnAddressRegister);
+}
+
 #else // CPU(X86) || CPU(X86_64)
 
 ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
 #else // CPU(X86) || CPU(X86_64)
 
 ALWAYS_INLINE void JIT::preserveReturnAddressAfterCall(RegisterID reg)
@@ -307,23 +333,13 @@ ALWAYS_INLINE void JIT::sampleCodeBlock(CodeBlock* codeBlock)
 #endif
 #endif
 
 #endif
 #endif
 
-inline JIT::Address JIT::addressFor(unsigned index, RegisterID base)
+ALWAYS_INLINE bool JIT::isOperandConstantImmediateChar(unsigned src)
 {
 {
-    return Address(base, (index * sizeof(Register)));
+    return m_codeBlock->isConstantRegisterIndex(src) && getConstantOperand(src).isString() && asString(getConstantOperand(src).asCell())->length() == 1;
 }
 
 #if USE(JSVALUE32_64)
 
 }
 
 #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 void JIT::emitLoadTag(unsigned index, RegisterID tag)
 {
     RegisterID mappedTag;
 inline void JIT::emitLoadTag(unsigned index, RegisterID tag)
 {
     RegisterID mappedTag;
@@ -543,14 +559,22 @@ inline bool JIT::getMappedTag(unsigned virtualRegisterIndex, RegisterID& tag)
 
 inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex)
 {
 
 inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex)
 {
-    if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex))
-        addSlowCase(branch32(NotEqual, tagFor(virtualRegisterIndex), Imm32(JSValue::CellTag)));
+    if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex)) {
+        if (m_codeBlock->isConstantRegisterIndex(virtualRegisterIndex))
+            addSlowCase(jump());
+        else
+            addSlowCase(emitJumpIfNotJSCell(virtualRegisterIndex));
+    }
 }
 
 inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, RegisterID tag)
 {
 }
 
 inline void JIT::emitJumpSlowCaseIfNotJSCell(unsigned virtualRegisterIndex, RegisterID tag)
 {
-    if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex))
-        addSlowCase(branch32(NotEqual, tag, Imm32(JSValue::CellTag)));
+    if (!m_codeBlock->isKnownNotImmediate(virtualRegisterIndex)) {
+        if (m_codeBlock->isConstantRegisterIndex(virtualRegisterIndex))
+            addSlowCase(jump());
+        else
+            addSlowCase(branch32(NotEqual, tag, Imm32(JSValue::CellTag)));
+    }
 }
 
 inline void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, unsigned virtualRegisterIndex)
 }
 
 inline void JIT::linkSlowCaseIfNotJSCell(Vector<SlowCaseEntry>::iterator& iter, unsigned virtualRegisterIndex)
@@ -721,14 +745,6 @@ ALWAYS_INLINE void JIT::emitJumpSlowCaseIfNotJSCell(RegisterID reg, int vReg)
 }
 
 #if USE(JSVALUE64)
 }
 
 #if USE(JSVALUE64)
-ALWAYS_INLINE JIT::Jump JIT::emitJumpIfImmediateNumber(RegisterID reg)
-{
-    return branchTestPtr(NonZero, reg, tagTypeNumberRegister);
-}
-ALWAYS_INLINE JIT::Jump JIT::emitJumpIfNotImmediateNumber(RegisterID reg)
-{
-    return branchTestPtr(Zero, reg, tagTypeNumberRegister);
-}
 
 inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value)
 {
 
 inline void JIT::emitLoadDouble(unsigned index, FPRegisterID value)
 {
@@ -812,15 +828,6 @@ ALWAYS_INLINE void JIT::emitFastArithReTagImmediate(RegisterID src, RegisterID d
 #endif
 }
 
 #endif
 }
 
-ALWAYS_INLINE void JIT::emitFastArithImmToInt(RegisterID reg)
-{
-#if USE(JSVALUE64)
-    UNUSED_PARAM(reg);
-#else
-    rshift32(Imm32(JSImmediate::IntegerPayloadShift), reg);
-#endif
-}
-
 // operand is int32_t, must have been zero-extended if register is 64-bit.
 ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest)
 {
 // operand is int32_t, must have been zero-extended if register is 64-bit.
 ALWAYS_INLINE void JIT::emitFastArithIntToImmNoCheck(RegisterID src, RegisterID dest)
 {
index d9a32d9ae39c6649067bb0909b14f749c3d49515..403a4546e400e0e5ac139c4d7466de071f14c062 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009 Apple Inc. All rights reserved.
 /*
  * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 namespace JSC {
 
 
 namespace JSC {
 
-#if USE(JSVALUE32_64)
-
-void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, 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.
-    load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_stringLength)), 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)
-    // VirtualCallLink Trampoline
-    // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
-    Label virtualCallLinkBegin = align();
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-
-    Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
-
-    Jump hasCodeBlock2 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
-    preserveReturnAddressAfterCall(regT3);
-    restoreArgumentReference();
-    Call callJSFunction2 = call();
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-    emitGetJITStubArg(2, regT1); // argCount
-    restoreReturnAddressBeforeReturn(regT3);
-    hasCodeBlock2.link(this);
-
-    // Check argCount matches callee arity.
-    Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1);
-    preserveReturnAddressAfterCall(regT3);
-    emitPutJITStubArg(regT3, 1); // return address
-    restoreArgumentReference();
-    Call callArityCheck2 = call();
-    move(regT1, callFrameRegister);
-    emitGetJITStubArg(2, regT1); // argCount
-    restoreReturnAddressBeforeReturn(regT3);
-    arityCheckOkay2.link(this);
-
-    isNativeFunc2.link(this);
-
-    compileOpCallInitializeCallFrame();
-
-    preserveReturnAddressAfterCall(regT3);
-    emitPutJITStubArg(regT3, 1); // return address
-    restoreArgumentReference();
-    Call callLazyLinkCall = call();
-    restoreReturnAddressBeforeReturn(regT3);
-    jump(regT0);
-#endif // ENABLE(JIT_OPTIMIZE_CALL)
-
-    // VirtualCall Trampoline
-    // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
-    Label virtualCallBegin = align();
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-
-    Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
-
-    Jump hasCodeBlock3 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
-    preserveReturnAddressAfterCall(regT3);
-    restoreArgumentReference();
-    Call callJSFunction1 = call();
-    emitGetJITStubArg(2, regT1); // argCount
-    restoreReturnAddressBeforeReturn(regT3);
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-    hasCodeBlock3.link(this);
-    
-    // Check argCount matches callee arity.
-    Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1);
-    preserveReturnAddressAfterCall(regT3);
-    emitPutJITStubArg(regT3, 1); // return address
-    restoreArgumentReference();
-    Call callArityCheck1 = call();
-    move(regT1, callFrameRegister);
-    emitGetJITStubArg(2, regT1); // argCount
-    restoreReturnAddressBeforeReturn(regT3);
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
-    arityCheckOkay3.link(this);
-
-    isNativeFunc3.link(this);
-
-    compileOpCallInitializeCallFrame();
-    loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0);
-    jump(regT0);
-
-#if CPU(X86) || CPU(ARM_TRADITIONAL)
-    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 CPU(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) || OS(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) || OS(LINUX)
-    // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register)
-    addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86Registers::ecx);
-
-    // Plant callee
-    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::eax);
-    storePtr(X86Registers::eax, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, callee)));
-
-    // Plant callframe
-    move(callFrameRegister, X86Registers::edx);
-
-    call(Address(X86Registers::eax, OBJECT_OFFSETOF(JSFunction, m_data)));
-
-    // JSValue is a non-POD type, so eax points to it
-    emitLoad(0, regT1, regT0, X86Registers::eax);
-#else
-    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::edx); // callee
-    move(callFrameRegister, X86Registers::ecx); // callFrame
-    call(Address(X86Registers::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 CPU(ARM_TRADITIONAL)
-    emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
-
-    // Allocate stack space for our arglist
-    COMPILE_ASSERT((sizeof(ArgList) & 0x7) == 0 && sizeof(JSValue) == 8 && sizeof(Register) == 8, ArgList_should_by_8byte_aligned);
-    subPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
-
-    // Set up arguments
-    subPtr(Imm32(1), regT0); // Don't include 'this' in argcount
-
-    // Push argcount
-    storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_argCount)));
-
-    // Calculate the start of the callframe header, and store in regT1
-    move(callFrameRegister, regT1);
-    sub32(Imm32(RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), regT1);
-
-    // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT1)
-    mul32(Imm32(sizeof(Register)), regT0, regT0);
-    subPtr(regT0, regT1);
-
-    // push pointer to arguments
-    storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args)));
-
-    // Argument passing method:
-    // r0 - points to return value
-    // r1 - callFrame
-    // r2 - callee
-    // stack: this(JSValue) and a pointer to ArgList
-
-    move(stackPointerRegister, regT3);
-    subPtr(Imm32(8), stackPointerRegister);
-    move(stackPointerRegister, regT0);
-    subPtr(Imm32(8 + 4 + 4 /* padding */), stackPointerRegister);
-
-    // Setup arg4:
-    storePtr(regT3, Address(stackPointerRegister, 8));
-
-    // Setup arg3
-    // regT1 currently points to the first argument, regT1-sizeof(Register) points to 'this'
-    load32(Address(regT1, -(int32_t)sizeof(void*) * 2), regT3);
-    storePtr(regT3, Address(stackPointerRegister, 0));
-    load32(Address(regT1, -(int32_t)sizeof(void*)), regT3);
-    storePtr(regT3, Address(stackPointerRegister, 4));
-
-    // Setup arg2:
-    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT2);
-
-    // Setup arg1:
-    move(callFrameRegister, regT1);
-
-    call(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data)));
-
-    // Load return value
-    load32(Address(stackPointerRegister, 16), regT0);
-    load32(Address(stackPointerRegister, 20), regT1);
-
-    addPtr(Imm32(sizeof(ArgList) + 16 + 8), stackPointerRegister);
-#endif
-
-    // Check for an exception
-    move(ImmPtr(&globalData->exception), regT2);
-    Jump sawException = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::EmptyValueTag));
-
-    // Grab the return address.
-    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT3);
-    
-    // Restore our caller's "r".
-    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
-    
-    // Return.
-    restoreReturnAddressBeforeReturn(regT3);
-    ret();
-
-    // Handle an exception
-    sawException.link(this);
-    // Grab the return address.
-    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
-    move(ImmPtr(&globalData->exceptionLocation), regT2);
-    storePtr(regT1, regT2);
-    move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), 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
-    patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck));
-    patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction));
-#if ENABLE(JIT_OPTIMIZE_CALL)
-    patchBuffer.link(callArityCheck2, FunctionPtr(cti_op_call_arityCheck));
-    patchBuffer.link(callJSFunction2, FunctionPtr(cti_op_call_JSFunction));
-    patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall));
-#endif
-
-    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)
-    *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
-#else
-    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);
-}
-
-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);
-        return;
-    }
-
-    if (isOperandConstantImmediateInt(op2)) {
-        emitLoad(op1, regT1, regT0);
-        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
-        addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
-        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);
-}
-
-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);
-}
-
-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 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(value, regT2);
-    emitLoadPayload(baseVal, regT0);
-    emitLoadPayload(proto, regT1);
-
-    // Check that value, baseVal, and proto are cells.
-    emitJumpSlowCaseIfNotJSCell(value);
-    emitJumpSlowCaseIfNotJSCell(baseVal);
-    emitJumpSlowCaseIfNotJSCell(proto);
-
-    // Check that baseVal 'ImplementsDefaultHasInstance'.
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
-    addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
-
-    // 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 cell 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);
-    branchTest32(NonZero, regT2).linkTo(loop, this);
-
-    // We get here either by dropping out of the loop, or if value was not an Object.  Result is false.
-    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, value);
-    linkSlowCaseIfNotJSCell(iter, baseVal);
-    linkSlowCaseIfNotJSCell(iter, proto);
-    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->functionDecl(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_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);
-
-    Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
-    Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0));
-    addJump(jump(), target);
-
-    if (supportsFloatingPoint()) {
-        isNotInteger.link(this);
-
-        addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
-
-        zeroDouble(fpRegT0);
-        emitLoadDouble(cond, fpRegT1);
-        addJump(branchDouble(DoubleEqualOrUnordered, fpRegT0, fpRegT1), target);
-    } 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); // 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);
-
-    Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
-    Jump isFalse2 = branch32(Equal, regT0, Imm32(0));
-    addJump(jump(), target);
-
-    if (supportsFloatingPoint()) {
-        isNotInteger.link(this);
-
-        addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
-
-        zeroDouble(fpRegT0);
-        emitLoadDouble(cond, fpRegT1);
-        addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target);
-    } 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);
-}
-
-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);
-
-    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);
-
-    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);
-
-    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);
-
-    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);
-    addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target);
-}
-
-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);
-    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->functionExpr(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_get_pnames(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int i = currentInstruction[3].u.operand;
-    int size = currentInstruction[4].u.operand;
-    int breakTarget = currentInstruction[5].u.operand;
-
-    JumpList isNotObject;
-
-    emitLoad(base, regT1, regT0);
-    if (!m_codeBlock->isKnownNotImmediate(base))
-        isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
-    if (base != m_codeBlock->thisRegister()) {
-        loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
-        isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
-    }
-
-    // We could inline the case where you have a valid cache, but
-    // this call doesn't seem to be hot.
-    Label isObject(this);
-    JITStubCall getPnamesStubCall(this, cti_op_get_pnames);
-    getPnamesStubCall.addArgument(regT0);
-    getPnamesStubCall.call(dst);
-    load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
-    store32(Imm32(0), addressFor(i));
-    store32(regT3, addressFor(size));
-    Jump end = jump();
-
-    isNotObject.link(this);
-    addJump(branch32(Equal, regT1, Imm32(JSValue::NullTag)), breakTarget);
-    addJump(branch32(Equal, regT1, Imm32(JSValue::UndefinedTag)), breakTarget);
-    JITStubCall toObjectStubCall(this, cti_to_object);
-    toObjectStubCall.addArgument(regT1, regT0);
-    toObjectStubCall.call(base);
-    jump().linkTo(isObject, this);
-    
-    end.link(this);
-}
-
-void JIT::emit_op_next_pname(Instruction* currentInstruction)
-{
-    int dst = currentInstruction[1].u.operand;
-    int base = currentInstruction[2].u.operand;
-    int i = currentInstruction[3].u.operand;
-    int size = currentInstruction[4].u.operand;
-    int it = currentInstruction[5].u.operand;
-    int target = currentInstruction[6].u.operand;
-    
-    JumpList callHasProperty;
-
-    Label begin(this);
-    load32(addressFor(i), regT0);
-    Jump end = branch32(Equal, regT0, addressFor(size));
-
-    // Grab key @ i
-    loadPtr(addressFor(it), regT1);
-    loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
-    load32(BaseIndex(regT2, regT0, TimesEight), regT2);
-    store32(Imm32(JSValue::CellTag), tagFor(dst));
-    store32(regT2, payloadFor(dst));
-
-    // Increment i
-    add32(Imm32(1), regT0);
-    store32(regT0, addressFor(i));
-
-    // Verify that i is valid:
-    loadPtr(addressFor(base), regT0);
-
-    // Test base's structure
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
-    callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))));
-
-    // Test base's prototype chain
-    loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3);
-    loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3);
-    addJump(branchTestPtr(Zero, Address(regT3)), target);
-
-    Label checkPrototype(this);
-    callHasProperty.append(branch32(Equal, Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::NullTag)));
-    loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
-    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
-    callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3)));
-    addPtr(Imm32(sizeof(Structure*)), regT3);
-    branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this);
-
-    // Continue loop.
-    addJump(jump(), target);
-
-    // Slow case: Ask the object if i is valid.
-    callHasProperty.link(this);
-    loadPtr(addressFor(dst), regT1);
-    JITStubCall stubCall(this, cti_has_property);
-    stubCall.addArgument(regT0);
-    stubCall.addArgument(regT1);
-    stubCall.call();
-
-    // Test for valid key.
-    addJump(branchTest32(NonZero, regT0), target);
-    jump().linkTo(begin, this);
-
-    // End of loop.
-    end.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::EmptyValueTag)));
-    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);
-}
-
-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 argsCreated = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::EmptyValueTag));
-
-    // 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();
-
-    argsCreated.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)
+#if !USE(JSVALUE32_64)
 
 #define RECORD_JUMP_TARGET(targetOffset) \
    do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false)
 
 
 #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* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk)
+void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines)
 {
 {
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    Label softModBegin = align();
+    softModulo();
+#endif
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
     // (2) The second function provides fast property access for string length
     Label stringLengthBegin = align();
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
     // (2) The second function provides fast property access for string length
     Label stringLengthBegin = align();
@@ -1506,7 +59,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
 
     // Checks out okay! - get the length from the Ustring.
     Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
 
     // Checks out okay! - get the length from the Ustring.
-    load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_stringLength)), regT0);
+    load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), regT0);
 
     Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
 
 
     Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
 
@@ -1753,7 +306,30 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     // push pointer to arguments
     storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args)));
 
     // push pointer to arguments
     storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args)));
 
-    // Setup arg3: regT1 currently points to the first argument, regT1-sizeof(Register) points to 'this'
+    // regT1 currently points to the first argument, regT1-sizeof(Register) points to 'this'
+
+#if OS(WINCE)
+    // Setup arg3:
+    loadPtr(Address(regT1, -(int32_t)sizeof(Register)), ARMRegisters::r3);
+
+    // Setup arg2:
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT2);
+
+    // Setup arg1:
+    move(callFrameRegister, regT1);
+
+    // Setup arg0:
+    move(stackPointerRegister, regT0);
+    subPtr(Imm32(sizeof(Register)), stackPointerRegister);
+    storePtr(regT0, Address(stackPointerRegister));
+
+    call(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data)));
+
+    loadPtr(Address(regT0), regT0);
+
+    addPtr(Imm32(sizeof(Register) + sizeof(ArgList)), stackPointerRegister);
+#else // OS(WINCE)
+    // Setup arg3:
     loadPtr(Address(regT1, -(int32_t)sizeof(Register)), regT2);
 
     // Setup arg2:
     loadPtr(Address(regT1, -(int32_t)sizeof(Register)), regT2);
 
     // Setup arg2:
@@ -1768,6 +344,57 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     call(Address(regT1, OBJECT_OFFSETOF(JSFunction, m_data)));
 
     addPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
     call(Address(regT1, OBJECT_OFFSETOF(JSFunction, m_data)));
 
     addPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
+#endif // OS(WINCE)
+
+#elif CPU(MIPS)
+    emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+
+    // Allocate stack space for our arglist
+    COMPILE_ASSERT(!(sizeof(ArgList) & 0x7), ArgList_should_by_8byte_aligned);
+    subPtr(Imm32(sizeof(ArgList) + 24), stackPointerRegister);
+
+    // Set up arguments
+    subPtr(Imm32(1), regT0); // Don't include 'this' in argcount
+
+    // Push argcount to 24 + offset($sp)
+    storePtr(regT0, Address(stackPointerRegister, 24 + OBJECT_OFFSETOF(ArgList, m_argCount)));
+
+    // Calculate the start of the callframe header, and store in regT1
+    move(callFrameRegister, regT1);
+    sub32(Imm32(RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), regT1);
+
+    // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT1)
+    mul32(Imm32(sizeof(Register)), regT0, regT0);
+    subPtr(regT0, regT1);
+
+    // push pointer to arguments to 24 + offset($sp)
+    storePtr(regT1, Address(stackPointerRegister, 24 + OBJECT_OFFSETOF(ArgList, m_args)));
+
+    // Setup arg3: regT1 currently points to the first argument, regT1-sizeof(Register) points to 'this'
+    loadPtr(Address(regT1, -(int32_t)sizeof(Register)), MIPSRegisters::a3);
+
+    // Setup arg2:
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2);
+
+    // Setup arg1:
+    move(callFrameRegister, MIPSRegisters::a1);
+
+    // Setup arg4: ArgList is passed by reference.  At 16($sp), store ($sp + 24)
+    addPtr(Imm32(24), stackPointerRegister, regT2);
+    storePtr(regT2, Address(stackPointerRegister, 16));
+
+    // Setup arg0 as 20($sp) to hold the returned structure.
+    ASSERT(sizeof(JSValue) == 4);
+    addPtr(Imm32(20), stackPointerRegister, MIPSRegisters::a0);
+
+    // Call
+    call(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_data)));
+
+    // Get returned value from 0($v0) which is the same as 20($sp)
+    loadPtr(Address(returnValueRegister, 0), returnValueRegister);
+
+    // Restore stack space
+    addPtr(Imm32(sizeof(ArgList) + 24), stackPointerRegister);
 
 #elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
 #error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
 
 #elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
 #error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
@@ -1827,11 +454,14 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
     CodeRef finalCode = patchBuffer.finalizeCode();
     *executablePool = finalCode.m_executablePool;
 
     CodeRef finalCode = patchBuffer.finalizeCode();
     *executablePool = finalCode.m_executablePool;
 
-    *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
-    *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
-    *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk);
+    trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
+    trampolines->ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
+    trampolines->ctiNativeCallThunk = adoptRef(new NativeExecutable(JITCode(JITCode::HostFunction(trampolineAt(finalCode, nativeCallThunk)))));
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin);
+#endif
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
-    *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
+    trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
 #else
     UNUSED_PARAM(ctiStringLengthTrampoline);
 #endif
 #else
     UNUSED_PARAM(ctiStringLengthTrampoline);
 #endif
@@ -1924,7 +554,7 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
 
     // Check that baseVal 'ImplementsDefaultHasInstance'.
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
 
     // Check that baseVal 'ImplementsDefaultHasInstance'.
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
-    addSlowCase(branchTest32(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
+    addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
 
     // Optimistically load the result true, and start looping.
     // Initially, regT1 still contains proto and regT2 still contains value.
 
     // Optimistically load the result true, and start looping.
     // Initially, regT1 still contains proto and regT2 still contains value.
@@ -2085,7 +715,7 @@ void JIT::emit_op_construct_verify(Instruction* currentInstruction)
 
     emitJumpSlowCaseIfNotJSCell(regT0);
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
 
     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)));
+    addSlowCase(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
 
 }
 
 
 }
 
@@ -2128,12 +758,10 @@ void JIT::emit_op_resolve_skip(Instruction* currentInstruction)
     stubCall.call(currentInstruction[1].u.operand);
 }
 
     stubCall.call(currentInstruction[1].u.operand);
 }
 
-void JIT::emit_op_resolve_global(Instruction* currentInstruction)
+void JIT::emit_op_resolve_global(Instruction* currentInstruction, bool)
 {
     // Fast case
     void* globalObject = currentInstruction[2].u.jsCell;
 {
     // 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);
     unsigned currentIndex = m_globalResolveInfoIndex++;
     void* structureAddress = &(m_codeBlock->globalResolveInfo(currentIndex).structure);
     void* offsetAddr = &(m_codeBlock->globalResolveInfo(currentIndex).offset);
@@ -2141,7 +769,7 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction)
     // Check Structure of global object
     move(ImmPtr(globalObject), regT0);
     loadPtr(structureAddress, regT1);
     // 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
+    addSlowCase(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.
 
     // Load cached property
     // Assume that the global object always uses external storage.
@@ -2149,16 +777,22 @@ void JIT::emit_op_resolve_global(Instruction* currentInstruction)
     load32(offsetAddr, regT1);
     loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
     emitPutVirtualRegister(currentInstruction[1].u.operand);
     load32(offsetAddr, regT1);
     loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
     emitPutVirtualRegister(currentInstruction[1].u.operand);
-    Jump end = jump();
+}
 
 
-    // Slow case
-    noMatch.link(this);
+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));
     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);
+    stubCall.call(dst);
 }
 
 void JIT::emit_op_not(Instruction* currentInstruction)
 }
 
 void JIT::emit_op_not(Instruction* currentInstruction)
@@ -2183,7 +817,8 @@ void JIT::emit_op_jfalse(Instruction* currentInstruction)
 
     isNonZero.link(this);
     RECORD_JUMP_TARGET(target);
 
     isNonZero.link(this);
     RECORD_JUMP_TARGET(target);
-};
+}
+
 void JIT::emit_op_jeq_null(Instruction* currentInstruction)
 {
     unsigned src = currentInstruction[1].u.operand;
 void JIT::emit_op_jeq_null(Instruction* currentInstruction)
 {
     unsigned src = currentInstruction[1].u.operand;
@@ -2194,7 +829,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
 
     // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
 
     // 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);
+    addJump(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
     Jump wasNotImmediate = jump();
 
     // Now handle the immediate cases - undefined & null
     Jump wasNotImmediate = jump();
 
     // Now handle the immediate cases - undefined & null
@@ -2215,7 +850,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
 
     // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
 
     // 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);
+    addJump(branchTest8(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
     Jump wasNotImmediate = jump();
 
     // Now handle the immediate cases - undefined & null
     Jump wasNotImmediate = jump();
 
     // Now handle the immediate cases - undefined & null
@@ -2328,13 +963,6 @@ void JIT::emit_op_bitxor(Instruction* currentInstruction)
     emitPutVirtualRegister(currentInstruction[1].u.operand);
 }
 
     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);
 void JIT::emit_op_bitor(Instruction* currentInstruction)
 {
     emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
@@ -2371,7 +999,7 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
         isNotObject.append(emitJumpIfNotJSCell(regT0));
     if (base != m_codeBlock->thisRegister()) {
         loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
         isNotObject.append(emitJumpIfNotJSCell(regT0));
     if (base != m_codeBlock->thisRegister()) {
         loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
-        isNotObject.append(branch32(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+        isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
     }
 
     // We could inline the case where you have a valid cache, but
     }
 
     // We could inline the case where you have a valid cache, but
@@ -2522,7 +1150,7 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
 
     emitJumpSlowCaseIfNotJSCell(regT0, srcVReg);
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
 
     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)));
+    addSlowCase(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
     
     wasImmediate.link(this);
 
     
     wasImmediate.link(this);
 
@@ -2617,11 +1245,16 @@ void JIT::emit_op_new_error(Instruction* currentInstruction)
 
 void JIT::emit_op_debug(Instruction* currentInstruction)
 {
 
 void JIT::emit_op_debug(Instruction* currentInstruction)
 {
+#if ENABLE(DEBUG_WITH_BREAKPOINT)
+    UNUSED_PARAM(currentInstruction);
+    breakpoint();
+#else
     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();
     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();
+#endif
 }
 
 void JIT::emit_op_eq_null(Instruction* currentInstruction)
 }
 
 void JIT::emit_op_eq_null(Instruction* currentInstruction)
@@ -2633,7 +1266,7 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
     Jump isImmediate = emitJumpIfNotJSCell(regT0);
 
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
     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);
+    setTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
 
     Jump wasNotImmediate = jump();
 
 
     Jump wasNotImmediate = jump();
 
@@ -2658,7 +1291,7 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
     Jump isImmediate = emitJumpIfNotJSCell(regT0);
 
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
     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);
+    setTest8(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
 
     Jump wasNotImmediate = jump();
 
 
     Jump wasNotImmediate = jump();
 
@@ -2718,7 +1351,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
 
     emitJumpSlowCaseIfNotJSCell(regT0);
     loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT1);
 
     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)));
+    addSlowCase(branchTest8(NonZero, Address(regT1, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
 
 }
 
 
 }
 
@@ -2774,24 +1407,6 @@ void JIT::emitSlow_op_to_primitive(Instruction* currentInstruction, Vector<SlowC
     stubCall.call(currentInstruction[1].u.operand);
 }
 
     stubCall.call(currentInstruction[1].u.operand);
 }
 
-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;
-
-    linkSlowCase(iter); // property int32 check
-    linkSlowCaseIfNotJSCell(iter, base); // base cell check
-    linkSlowCase(iter); // base array check
-    linkSlowCase(iter); // vector length check
-    linkSlowCase(iter); // empty value
-
-    JITStubCall stubCall(this, cti_op_get_by_val);
-    stubCall.addArgument(base, regT2);
-    stubCall.addArgument(property, regT2);
-    stubCall.call(dst);
-}
-
 void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     unsigned op2 = currentInstruction[2].u.operand;
 void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     unsigned op2 = currentInstruction[2].u.operand;
@@ -2976,8 +1591,126 @@ void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCa
     stubCall.call(currentInstruction[1].u.operand);
 }
 
     stubCall.call(currentInstruction[1].u.operand);
 }
 
-#endif // USE(JSVALUE32_64)
+#endif // !USE(JSVALUE32_64)
+
+void JIT::emit_op_resolve_global_dynamic(Instruction* currentInstruction)
+{
+    int skip = currentInstruction[6].u.operand + m_codeBlock->needsFullScopeChain();
+    
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT0);
+    while (skip--) {
+        loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, object)), regT1);
+        addSlowCase(checkStructure(regT1, m_globalData->activationStructure.get()));
+        loadPtr(Address(regT0, OBJECT_OFFSETOF(ScopeChainNode, next)), regT0);
+    }
+    emit_op_resolve_global(currentInstruction, true);
+}
+
+void JIT::emitSlow_op_resolve_global_dynamic(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);
+    int skip = currentInstruction[6].u.operand + m_codeBlock->needsFullScopeChain();
+    while (skip--)
+        linkSlowCase(iter);
+    JITStubCall resolveStubCall(this, cti_op_resolve);
+    resolveStubCall.addArgument(ImmPtr(ident));
+    resolveStubCall.call(dst);
+    emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_resolve_global_dynamic));
+    
+    unsigned currentIndex = m_globalResolveInfoIndex++;
+    
+    linkSlowCase(iter); // We managed to skip all the nodes in the scope chain, but the cache missed.
+    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_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);
+}
+
+// For both JSValue32_64 and JSValue32
+#if ENABLE(JIT_OPTIMIZE_MOD)
+#if CPU(ARM_TRADITIONAL)
+void JIT::softModulo()
+{
+    push(regS0);
+    push(regS1);
+    push(regT1);
+    push(regT3);
+#if USE(JSVALUE32_64)
+    m_assembler.mov_r(regT3, regT2);
+    m_assembler.mov_r(regT2, regT0);
+#else
+    m_assembler.mov_r(regT3, m_assembler.asr(regT2, 1));
+    m_assembler.mov_r(regT2, m_assembler.asr(regT0, 1));
+#endif
+    m_assembler.mov_r(regT1, ARMAssembler::getOp2(0));
+    
+    m_assembler.teq_r(regT3, ARMAssembler::getOp2(0));
+    m_assembler.rsb_r(regT3, regT3, ARMAssembler::getOp2(0), ARMAssembler::MI);
+    m_assembler.eor_r(regT1, regT1, ARMAssembler::getOp2(1), ARMAssembler::MI);
+    
+    m_assembler.teq_r(regT2, ARMAssembler::getOp2(0));
+    m_assembler.rsb_r(regT2, regT2, ARMAssembler::getOp2(0), ARMAssembler::MI);
+    m_assembler.eor_r(regT1, regT1, ARMAssembler::getOp2(2), ARMAssembler::MI);
+    
+    Jump exitBranch = branch32(LessThan, regT2, regT3);
+
+    m_assembler.sub_r(regS1, regT3, ARMAssembler::getOp2(1));
+    m_assembler.tst_r(regS1, regT3);
+    m_assembler.and_r(regT2, regT2, regS1, ARMAssembler::EQ);
+    m_assembler.and_r(regT0, regS1, regT3);
+    Jump exitBranch2 = branchTest32(Zero, regT0);
+    
+    m_assembler.clz_r(regS1, regT2);
+    m_assembler.clz_r(regS0, regT3);
+    m_assembler.sub_r(regS0, regS0, regS1);
+
+    m_assembler.rsbs_r(regS0, regS0, ARMAssembler::getOp2(31));
+
+    m_assembler.mov_r(regS0, m_assembler.lsl(regS0, 1), ARMAssembler::NE);
+
+    m_assembler.add_r(ARMRegisters::pc, ARMRegisters::pc, m_assembler.lsl(regS0, 2), ARMAssembler::NE);
+    m_assembler.mov_r(regT0, regT0);
+    
+    for (int i = 31; i > 0; --i) {
+        m_assembler.cmp_r(regT2, m_assembler.lsl(regT3, i));
+        m_assembler.sub_r(regT2, regT2, m_assembler.lsl(regT3, i), ARMAssembler::CS);
+    }
 
 
+    m_assembler.cmp_r(regT2, regT3);
+    m_assembler.sub_r(regT2, regT2, regT3, ARMAssembler::CS);
+    
+    exitBranch.link(this);
+    exitBranch2.link(this);
+    
+    m_assembler.teq_r(regT1, ARMAssembler::getOp2(0));
+    m_assembler.rsb_r(regT2, regT2, ARMAssembler::getOp2(0), ARMAssembler::GT);
+    
+#if USE(JSVALUE32_64)
+    m_assembler.mov_r(regT0, regT2);
+#else
+    m_assembler.mov_r(regT0, m_assembler.lsl(regT2, 1));
+    m_assembler.eor_r(regT0, regT0, ARMAssembler::getOp2(1));
+#endif
+    pop(regT3);
+    pop(regT1);
+    pop(regS1);
+    pop(regS0);
+    ret();
+}
+#else
+#error "JIT_OPTIMIZE_MOD not yet supported on this platform."
+#endif // CPU(ARM_TRADITIONAL)
+#endif
 } // namespace JSC
 
 #endif // ENABLE(JIT)
 } // namespace JSC
 
 #endif // ENABLE(JIT)
diff --git a/jit/JITOpcodes32_64.cpp b/jit/JITOpcodes32_64.cpp
new file mode 100644 (file)
index 0000000..217aac0
--- /dev/null
@@ -0,0 +1,1531 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.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.
+ *
+ * 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) && USE(JSVALUE32_64)
+
+#include "JITInlineMethods.h"
+#include "JITStubCall.h"
+#include "JSArray.h"
+#include "JSCell.h"
+#include "JSFunction.h"
+#include "JSPropertyNameIterator.h"
+#include "LinkBuffer.h"
+
+namespace JSC {
+
+void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines)
+{
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    Label softModBegin = align();
+    softModulo();
+#endif
+#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.
+    load32(Address(regT0, OBJECT_OFFSETOF(JSString, m_length)), 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)
+    // VirtualCallLink Trampoline
+    // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
+    Label virtualCallLinkBegin = align();
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+
+    Jump isNativeFunc2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
+
+    Jump hasCodeBlock2 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
+    preserveReturnAddressAfterCall(regT3);
+    restoreArgumentReference();
+    Call callJSFunction2 = call();
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+    emitGetJITStubArg(2, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3);
+    hasCodeBlock2.link(this);
+
+    // Check argCount matches callee arity.
+    Jump arityCheckOkay2 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1);
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 1); // return address
+    restoreArgumentReference();
+    Call callArityCheck2 = call();
+    move(regT1, callFrameRegister);
+    emitGetJITStubArg(2, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3);
+    arityCheckOkay2.link(this);
+
+    isNativeFunc2.link(this);
+
+    compileOpCallInitializeCallFrame();
+
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 1); // return address
+    restoreArgumentReference();
+    Call callLazyLinkCall = call();
+    restoreReturnAddressBeforeReturn(regT3);
+    jump(regT0);
+#endif // ENABLE(JIT_OPTIMIZE_CALL)
+
+    // VirtualCall Trampoline
+    // regT0 holds callee, regT1 holds argCount.  regT2 will hold the FunctionExecutable.
+    Label virtualCallBegin = align();
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+
+    Jump isNativeFunc3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
+
+    Jump hasCodeBlock3 = branch32(GreaterThan, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), Imm32(0));
+    preserveReturnAddressAfterCall(regT3);
+    restoreArgumentReference();
+    Call callJSFunction1 = call();
+    emitGetJITStubArg(2, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3);
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+    hasCodeBlock3.link(this);
+
+    // Check argCount matches callee arity.
+    Jump arityCheckOkay3 = branch32(Equal, Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_numParameters)), regT1);
+    preserveReturnAddressAfterCall(regT3);
+    emitPutJITStubArg(regT3, 1); // return address
+    restoreArgumentReference();
+    Call callArityCheck1 = call();
+    move(regT1, callFrameRegister);
+    emitGetJITStubArg(2, regT1); // argCount
+    restoreReturnAddressBeforeReturn(regT3);
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
+    arityCheckOkay3.link(this);
+
+    isNativeFunc3.link(this);
+
+    compileOpCallInitializeCallFrame();
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(FunctionExecutable, m_jitCode)), regT0);
+    jump(regT0);
+
+#if CPU(X86) || CPU(ARM_TRADITIONAL)
+    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 CPU(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) || OS(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) || OS(LINUX)
+    // ArgList is passed by reference so is stackPointerRegister + 4 * sizeof(Register)
+    addPtr(Imm32(OBJECT_OFFSETOF(NativeCallFrameStructure, result)), stackPointerRegister, X86Registers::ecx);
+
+    // Plant callee
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::eax);
+    storePtr(X86Registers::eax, Address(stackPointerRegister, OBJECT_OFFSETOF(NativeCallFrameStructure, callee)));
+
+    // Plant callframe
+    move(callFrameRegister, X86Registers::edx);
+
+    call(Address(X86Registers::eax, OBJECT_OFFSETOF(JSFunction, m_data)));
+
+    // JSValue is a non-POD type, so eax points to it
+    emitLoad(0, regT1, regT0, X86Registers::eax);
+#else
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, X86Registers::edx); // callee
+    move(callFrameRegister, X86Registers::ecx); // callFrame
+    call(Address(X86Registers::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 CPU(ARM_TRADITIONAL)
+    emitGetFromCallFrameHeader32(RegisterFile::ArgumentCount, regT0);
+
+    // Allocate stack space for our arglist
+    COMPILE_ASSERT((sizeof(ArgList) & 0x7) == 0 && sizeof(JSValue) == 8 && sizeof(Register) == 8, ArgList_should_by_8byte_aligned);
+    subPtr(Imm32(sizeof(ArgList)), stackPointerRegister);
+
+    // Set up arguments
+    subPtr(Imm32(1), regT0); // Don't include 'this' in argcount
+
+    // Push argcount
+    storePtr(regT0, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_argCount)));
+
+    // Calculate the start of the callframe header, and store in regT1
+    move(callFrameRegister, regT1);
+    sub32(Imm32(RegisterFile::CallFrameHeaderSize * (int32_t)sizeof(Register)), regT1);
+
+    // Calculate start of arguments as callframe header - sizeof(Register) * argcount (regT1)
+    mul32(Imm32(sizeof(Register)), regT0, regT0);
+    subPtr(regT0, regT1);
+
+    // push pointer to arguments
+    storePtr(regT1, Address(stackPointerRegister, OBJECT_OFFSETOF(ArgList, m_args)));
+
+    // Argument passing method:
+    // r0 - points to return value
+    // r1 - callFrame
+    // r2 - callee
+    // stack: this(JSValue) and a pointer to ArgList
+
+#if OS(WINCE)
+    // Setup arg4:
+    push(stackPointerRegister);
+
+    // Setup arg3:
+    // regT1 currently points to the first argument, regT1-sizeof(Register) points to 'this'
+    load32(Address(regT1, -(int32_t)sizeof(void*) * 2), ARMRegisters::r3);
+    push(ARMRegisters::r3);
+    load32(Address(regT1, -(int32_t)sizeof(void*)), regT3);
+    storePtr(regT3, Address(stackPointerRegister));
+
+    // Setup arg2:
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT2);
+
+    // Setup arg1:
+    move(callFrameRegister, regT1);
+
+    // Setup arg0:
+    move(stackPointerRegister, regT0);
+
+    call(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data)));
+
+    load32(Address(stackPointerRegister, 0), regT0);
+    load32(Address(stackPointerRegister, 4), regT1);
+
+    addPtr(Imm32(sizeof(ArgList) + 8), stackPointerRegister);
+#else // OS(WINCE)
+    move(stackPointerRegister, regT3);
+    subPtr(Imm32(8), stackPointerRegister);
+    move(stackPointerRegister, regT0);
+    subPtr(Imm32(8 + 4 + 4 /* padding */), stackPointerRegister);
+
+    // Setup arg4:
+    storePtr(regT3, Address(stackPointerRegister, 8));
+
+    // Setup arg3:
+    // regT1 currently points to the first argument, regT1-sizeof(Register) points to 'this'
+    load32(Address(regT1, -(int32_t)sizeof(void*) * 2), regT3);
+    storePtr(regT3, Address(stackPointerRegister, 0));
+    load32(Address(regT1, -(int32_t)sizeof(void*)), regT3);
+    storePtr(regT3, Address(stackPointerRegister, 4));
+
+    // Setup arg2:
+    emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, regT2);
+
+    // Setup arg1:
+    move(callFrameRegister, regT1);
+
+    call(Address(regT2, OBJECT_OFFSETOF(JSFunction, m_data)));
+
+    // Load return value
+    load32(Address(stackPointerRegister, 16), regT0);
+    load32(Address(stackPointerRegister, 20), regT1);
+
+    addPtr(Imm32(sizeof(ArgList) + 16 + 8), stackPointerRegister);
+#endif // OS(WINCE)
+
+#endif
+
+    // Check for an exception
+    move(ImmPtr(&globalData->exception), regT2);
+    Jump sawException = branch32(NotEqual, tagFor(0, regT2), Imm32(JSValue::EmptyValueTag));
+
+    // Grab the return address.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT3);
+
+    // Restore our caller's "r".
+    emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, callFrameRegister);
+
+    // Return.
+    restoreReturnAddressBeforeReturn(regT3);
+    ret();
+
+    // Handle an exception
+    sawException.link(this);
+    // Grab the return address.
+    emitGetFromCallFrameHeaderPtr(RegisterFile::ReturnPC, regT1);
+    move(ImmPtr(&globalData->exceptionLocation), regT2);
+    storePtr(regT1, regT2);
+    move(ImmPtr(FunctionPtr(ctiVMThrowTrampoline).value()), 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
+    UNUSED_PARAM(globalData);
+    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
+    patchBuffer.link(callArityCheck1, FunctionPtr(cti_op_call_arityCheck));
+    patchBuffer.link(callJSFunction1, FunctionPtr(cti_op_call_JSFunction));
+#if ENABLE(JIT_OPTIMIZE_CALL)
+    patchBuffer.link(callArityCheck2, FunctionPtr(cti_op_call_arityCheck));
+    patchBuffer.link(callJSFunction2, FunctionPtr(cti_op_call_JSFunction));
+    patchBuffer.link(callLazyLinkCall, FunctionPtr(cti_vm_lazyLinkCall));
+#endif
+
+    CodeRef finalCode = patchBuffer.finalizeCode();
+    *executablePool = finalCode.m_executablePool;
+
+    trampolines->ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin);
+#if ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
+    trampolines->ctiNativeCallThunk = adoptRef(new NativeExecutable(JITCode(JITCode::HostFunction(trampolineAt(finalCode, nativeCallThunk)))));
+#endif
+#if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
+    trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin);
+#else
+    UNUSED_PARAM(ctiStringLengthTrampoline);
+#endif
+#if ENABLE(JIT_OPTIMIZE_CALL)
+    trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin);
+#else
+    UNUSED_PARAM(ctiVirtualCallLink);
+#endif
+#if ENABLE(JIT_OPTIMIZE_MOD)
+    trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin);
+#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);
+}
+
+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);
+        return;
+    }
+
+    if (isOperandConstantImmediateInt(op2)) {
+        emitLoad(op1, regT1, regT0);
+        addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
+        addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
+        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);
+}
+
+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);
+}
+
+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 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(value, regT2);
+    emitLoadPayload(baseVal, regT0);
+    emitLoadPayload(proto, regT1);
+
+    // Check that value, baseVal, and proto are cells.
+    emitJumpSlowCaseIfNotJSCell(value);
+    emitJumpSlowCaseIfNotJSCell(baseVal);
+    emitJumpSlowCaseIfNotJSCell(proto);
+
+    // Check that baseVal 'ImplementsDefaultHasInstance'.
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+    addSlowCase(branchTest8(Zero, Address(regT0, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(ImplementsDefaultHasInstance)));
+
+    // 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 cell 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);
+    branchTest32(NonZero, regT2).linkTo(loop, this);
+
+    // We get here either by dropping out of the loop, or if value was not an Object.  Result is false.
+    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, value);
+    linkSlowCaseIfNotJSCell(iter, baseVal);
+    linkSlowCaseIfNotJSCell(iter, proto);
+    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->functionDecl(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_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, bool dynamic)
+{
+    // 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 + dynamic ? OPCODE_LENGTH(op_resolve_global_dynamic) : 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);
+
+    Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+    Jump isTrue2 = branch32(NotEqual, regT0, Imm32(0));
+    addJump(jump(), target);
+
+    if (supportsFloatingPoint()) {
+        isNotInteger.link(this);
+
+        addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+
+        zeroDouble(fpRegT0);
+        emitLoadDouble(cond, fpRegT1);
+        addJump(branchDouble(DoubleEqualOrUnordered, fpRegT0, fpRegT1), target);
+    } 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); // 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);
+
+    Jump isNotInteger = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
+    Jump isFalse2 = branch32(Equal, regT0, Imm32(0));
+    addJump(jump(), target);
+
+    if (supportsFloatingPoint()) {
+        isNotInteger.link(this);
+
+        addSlowCase(branch32(Above, regT1, Imm32(JSValue::LowestTag)));
+
+        zeroDouble(fpRegT0);
+        emitLoadDouble(cond, fpRegT1);
+        addJump(branchDouble(DoubleNotEqual, fpRegT0, fpRegT1), target);
+    } 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);
+}
+
+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(branchTest8(NonZero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
+
+    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);
+
+    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(branchTest8(Zero, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target);
+
+    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);
+
+    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);
+    addJump(branchPtr(NotEqual, regT0, ImmPtr(ptr)), target);
+}
+
+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);
+    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->functionExpr(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_get_pnames(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int i = currentInstruction[3].u.operand;
+    int size = currentInstruction[4].u.operand;
+    int breakTarget = currentInstruction[5].u.operand;
+
+    JumpList isNotObject;
+
+    emitLoad(base, regT1, regT0);
+    if (!m_codeBlock->isKnownNotImmediate(base))
+        isNotObject.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag)));
+    if (base != m_codeBlock->thisRegister()) {
+        loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+        isNotObject.append(branch8(NotEqual, Address(regT2, OBJECT_OFFSETOF(Structure, m_typeInfo.m_type)), Imm32(ObjectType)));
+    }
+
+    // We could inline the case where you have a valid cache, but
+    // this call doesn't seem to be hot.
+    Label isObject(this);
+    JITStubCall getPnamesStubCall(this, cti_op_get_pnames);
+    getPnamesStubCall.addArgument(regT0);
+    getPnamesStubCall.call(dst);
+    load32(Address(regT0, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStringsSize)), regT3);
+    store32(Imm32(0), addressFor(i));
+    store32(regT3, addressFor(size));
+    Jump end = jump();
+
+    isNotObject.link(this);
+    addJump(branch32(Equal, regT1, Imm32(JSValue::NullTag)), breakTarget);
+    addJump(branch32(Equal, regT1, Imm32(JSValue::UndefinedTag)), breakTarget);
+    JITStubCall toObjectStubCall(this, cti_to_object);
+    toObjectStubCall.addArgument(regT1, regT0);
+    toObjectStubCall.call(base);
+    jump().linkTo(isObject, this);
+
+    end.link(this);
+}
+
+void JIT::emit_op_next_pname(Instruction* currentInstruction)
+{
+    int dst = currentInstruction[1].u.operand;
+    int base = currentInstruction[2].u.operand;
+    int i = currentInstruction[3].u.operand;
+    int size = currentInstruction[4].u.operand;
+    int it = currentInstruction[5].u.operand;
+    int target = currentInstruction[6].u.operand;
+
+    JumpList callHasProperty;
+
+    Label begin(this);
+    load32(addressFor(i), regT0);
+    Jump end = branch32(Equal, regT0, addressFor(size));
+
+    // Grab key @ i
+    loadPtr(addressFor(it), regT1);
+    loadPtr(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_jsStrings)), regT2);
+    load32(BaseIndex(regT2, regT0, TimesEight), regT2);
+    store32(Imm32(JSValue::CellTag), tagFor(dst));
+    store32(regT2, payloadFor(dst));
+
+    // Increment i
+    add32(Imm32(1), regT0);
+    store32(regT0, addressFor(i));
+
+    // Verify that i is valid:
+    loadPtr(addressFor(base), regT0);
+
+    // Test base's structure
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    callHasProperty.append(branchPtr(NotEqual, regT2, Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure)))));
+
+    // Test base's prototype chain
+    loadPtr(Address(Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedPrototypeChain))), regT3);
+    loadPtr(Address(regT3, OBJECT_OFFSETOF(StructureChain, m_vector)), regT3);
+    addJump(branchTestPtr(Zero, Address(regT3)), target);
+
+    Label checkPrototype(this);
+    callHasProperty.append(branch32(Equal, Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), Imm32(JSValue::NullTag)));
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(Structure, m_prototype) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT2);
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT2);
+    callHasProperty.append(branchPtr(NotEqual, regT2, Address(regT3)));
+    addPtr(Imm32(sizeof(Structure*)), regT3);
+    branchTestPtr(NonZero, Address(regT3)).linkTo(checkPrototype, this);
+
+    // Continue loop.
+    addJump(jump(), target);
+
+    // Slow case: Ask the object if i is valid.
+    callHasProperty.link(this);
+    loadPtr(addressFor(dst), regT1);
+    JITStubCall stubCall(this, cti_has_property);
+    stubCall.addArgument(regT0);
+    stubCall.addArgument(regT1);
+    stubCall.call();
+
+    // Test for valid key.
+    addJump(branchTest32(NonZero, regT0), target);
+    jump().linkTo(begin, this);
+
+    // End of loop.
+    end.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::EmptyValueTag)));
+    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);
+}
+
+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)
+{
+#if ENABLE(DEBUG_WITH_BREAKPOINT)
+    UNUSED_PARAM(currentInstruction);
+    breakpoint();
+#else
+    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();
+#endif
+}
+
+
+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 argsCreated = branch32(NotEqual, tagFor(RegisterFile::ArgumentsRegister, callFrameRegister), Imm32(JSValue::EmptyValueTag));
+
+    // 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();
+
+    argsCreated.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(branchTest8(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);
+}
+
+}
+
+#endif // ENABLE(JIT) && USE(JSVALUE32_64)
index ef95f996afb0a26421c56092eb10ffd502c112ea..df969fa185fc674e2a54a2ba1430444ab70bc56e 100644 (file)
  */
 
 #include "config.h"
  */
 
 #include "config.h"
-#include "JIT.h"
-
-#if ENABLE(JIT)
-
-#include "CodeBlock.h"
-#include "JITInlineMethods.h"
-#include "JITStubCall.h"
-#include "JSArray.h"
-#include "JSFunction.h"
-#include "JSPropertyNameIterator.h"
-#include "Interpreter.h"
-#include "LinkBuffer.h"
-#include "RepatchBuffer.h"
-#include "ResultType.h"
-#include "SamplingTool.h"
-
-#ifndef NDEBUG
-#include <stdio.h>
-#endif
-
-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)
-
-/* ------------------------------ 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);
-
-    BEGIN_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
-
-    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);
-    END_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
-    
-    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)));
-
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
-    addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
-
-    load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag
-    load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload
-    addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag)));
-
-    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;
-
-    linkSlowCase(iter); // property int32 check
-    linkSlowCaseIfNotJSCell(iter, base); // base cell check
-    linkSlowCase(iter); // base array check
-    linkSlowCase(iter); // vector length check
-    linkSlowCase(iter); // empty value
-
-    JITStubCall stubCall(this, cti_op_get_by_val);
-    stubCall.addArgument(base);
-    stubCall.addArgument(property);
-    stubCall.call(dst);
-}
-
-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)));
-    addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
-
-    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
-
-    Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::EmptyValueTag));
-
-    Label storeResult(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
-    Jump end = jump();
-
-    empty.link(this);
-    add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
-    branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this);
-
-    add32(Imm32(1), regT2, regT0);
-    store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)));
-    jump().linkTo(storeResult, this);
-
-    end.link(this);
-}
-
-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
-    linkSlowCase(iter); // in vector check
-
-    JITStubCall stubPutByValCall(this, cti_op_put_by_val);
-    stubPutByValCall.addArgument(base);
-    stubPutByValCall.addArgument(property);
-    stubPutByValCall.addArgument(value);
-    stubPutByValCall.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.
-
-    BEGIN_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
-    
-    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);
-
-    END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
-}
-
-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);
-
-    BEGIN_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
-
-#ifndef NDEBUG
-    Label coldPathBegin(this);
-#endif
-    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);
-
-    END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
-
-    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);
-
-    BEGIN_UNINTERRUPTED_SEQUENCE(sequencePutById);
-
-    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
-
-    END_UNINTERRUPTED_SEQUENCE(sequencePutById);
-
-    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::testPrototype(Structure* structure, JumpList& failureCases)
-{
-    if (structure->m_prototype.isNull())
-        return;
-
-    failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(structure->m_prototype)->m_structure), ImmPtr(asCell(structure->m_prototype)->m_structure)));
-}
-
-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)));
-    failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure)));
-    testPrototype(oldStructure, failureCases);
-
-    // Verify that nothing in the prototype chain has a setter for this property. 
-    for (RefPtr<Structure>* it = chain->head(); *it; ++it)
-        testPrototype(it->get(), failureCases);
-
-    // 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, ReturnAddressPtr returnAddress)
-{
-    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);
-
-    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id));
-}
-
-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 CPU(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);
+#if !USE(JSVALUE32_64)
 
 
-    // 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);
-}
+#include "JIT.h"
 
 
-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));
+#if ENABLE(JIT)
 
 
-    // Check eax is an object of the right Structure.
-    Jump failureCases1 = checkStructure(regT0, structure);
+#include "CodeBlock.h"
+#include "GetterSetter.h"
+#include "JITInlineMethods.h"
+#include "JITStubCall.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "JSPropertyNameIterator.h"
+#include "Interpreter.h"
+#include "LinkBuffer.h"
+#include "RepatchBuffer.h"
+#include "ResultType.h"
+#include "SamplingTool.h"
 
 
-    // Check the prototype object's Structure had not changed.
-    Structure** prototypeStructureAddress = &(protoObject->m_structure);
-#if CPU(X86_64)
-    move(ImmPtr(prototypeStructure), regT3);
-    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
-#else
-    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+#ifndef NDEBUG
+#include <stdio.h>
 #endif
 
 #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);
+using namespace std;
 
 
-    // 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);
-}
+namespace JSC {
 
 
-void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, CallFrame* callFrame)
+PassRefPtr<NativeExecutable> JIT::stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool)
 {
 {
-    // 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 CPU(X86_64)
-        move(ImmPtr(currStructure), regT3);
-        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3));
+    JSInterfaceJIT jit;
+    JumpList failures;
+    failures.append(jit.branchPtr(NotEqual, Address(regT0), ImmPtr(globalData->jsStringVPtr)));
+    failures.append(jit.branchTest32(NonZero, Address(regT0, OBJECT_OFFSETOF(JSString, m_fiberCount))));
+#if USE(JSVALUE64)
+    jit.zeroExtend32ToPtr(regT1, regT1);
 #else
 #else
-        bucketsOfFail.append(branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(currStructure)));
+    jit.emitFastArithImmToInt(regT1);
 #endif
 #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*
+    // Load string length to regT1, and start the process of loading the data pointer into regT0
+    jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT2);
+    jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0);
+    jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
     
     
-    ASSERT(count);
+    // Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
+    failures.append(jit.branch32(AboveOrEqual, regT1, regT2));
     
     
-    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 CPU(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)
-
-void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset)
-{
-    ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
-    ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t));
-    ASSERT(sizeof(JSValue) == 8);
-
-    Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity));
-    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
-    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
-    Jump finishedLoad = jump();
-    notUsingInlineStorage.link(this);
-    loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
-    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
-    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
-    finishedLoad.link(this);
-}
-
-void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
-{
-    unsigned dst = currentInstruction[1].u.operand;
-    unsigned base = currentInstruction[2].u.operand;
-    unsigned property = currentInstruction[3].u.operand;
-    unsigned expected = currentInstruction[4].u.operand;
-    unsigned iter = currentInstruction[5].u.operand;
-    unsigned i = currentInstruction[6].u.operand;
-
-    emitLoad2(property, regT1, regT0, base, regT3, regT2);
-    emitJumpSlowCaseIfNotJSCell(property, regT1);
-    addSlowCase(branchPtr(NotEqual, regT0, payloadFor(expected)));
-    // Property registers are now available as the property is known
-    emitJumpSlowCaseIfNotJSCell(base, regT3);
-    emitLoadPayload(iter, regT1);
+    // Load the character
+    jit.load16(BaseIndex(regT0, regT1, TimesTwo, 0), regT0);
     
     
-    // Test base's structure
-    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
-    addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))));
-    load32(addressFor(i), regT3);
-    sub32(Imm32(1), regT3);
-    addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
-    compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3);    
-
-    emitStore(dst, regT1, regT0);
-    map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0);
-}
-
-void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    unsigned dst = currentInstruction[1].u.operand;
-    unsigned base = currentInstruction[2].u.operand;
-    unsigned property = currentInstruction[3].u.operand;
+    failures.append(jit.branch32(AboveOrEqual, regT0, Imm32(0x100)));
+    jit.move(ImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
+    jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0);
+    jit.ret();
     
     
-    linkSlowCaseIfNotJSCell(iter, property);
-    linkSlowCase(iter);
-    linkSlowCaseIfNotJSCell(iter, base);
-    linkSlowCase(iter);
-    linkSlowCase(iter);
+    failures.link(&jit);
+    jit.move(Imm32(0), regT0);
+    jit.ret();
     
     
-    JITStubCall stubCall(this, cti_op_get_by_val);
-    stubCall.addArgument(base);
-    stubCall.addArgument(property);
-    stubCall.call(dst);
+    LinkBuffer patchBuffer(&jit, pool);
+    return adoptRef(new NativeExecutable(patchBuffer.finalizeCode()));
 }
 
 }
 
-#else // USE(JSVALUE32_64)
-
 void JIT::emit_op_get_by_val(Instruction* currentInstruction)
 {
     unsigned dst = currentInstruction[1].u.operand;
 void JIT::emit_op_get_by_val(Instruction* currentInstruction)
 {
     unsigned dst = currentInstruction[1].u.operand;
@@ -1051,6 +119,34 @@ void JIT::emit_op_get_by_val(Instruction* currentInstruction)
     emitPutVirtualRegister(dst);
 }
 
     emitPutVirtualRegister(dst);
 }
 
+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;
+    
+    linkSlowCase(iter); // property int32 check
+    linkSlowCaseIfNotJSCell(iter, base); // base cell check
+    Jump nonCell = jump();
+    linkSlowCase(iter); // base array check
+    Jump notString = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
+    emitNakedCall(m_globalData->getThunk(stringGetByValStubGenerator)->generatedJITCode().addressForCall());
+    Jump failed = branchTestPtr(Zero, regT0);
+    emitPutVirtualRegister(dst, regT0);
+    emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
+    failed.link(this);
+    notString.link(this);
+    nonCell.link(this);
+    
+    linkSlowCase(iter); // vector length check
+    linkSlowCase(iter); // empty value
+    
+    JITStubCall stubCall(this, cti_op_get_by_val);
+    stubCall.addArgument(base, regT2);
+    stubCall.addArgument(property, regT2);
+    stubCall.call(dst);
+}
+
 void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch)
 {
     ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
 void JIT::compileGetDirectOffset(RegisterID base, RegisterID result, RegisterID structure, RegisterID offset, RegisterID scratch)
 {
     ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
@@ -1218,10 +314,11 @@ void JIT::emit_op_put_by_id(Instruction* currentInstruction)
     unsigned baseVReg = currentInstruction[1].u.operand;
     Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
     unsigned valueVReg = currentInstruction[3].u.operand;
     unsigned baseVReg = currentInstruction[1].u.operand;
     Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
     unsigned valueVReg = currentInstruction[3].u.operand;
+    unsigned direct = currentInstruction[8].u.operand;
 
     emitGetVirtualRegisters(baseVReg, regT0, valueVReg, regT1);
 
 
     emitGetVirtualRegisters(baseVReg, regT0, valueVReg, regT1);
 
-    JITStubCall stubCall(this, cti_op_put_by_id_generic);
+    JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct_generic, cti_op_put_by_id_generic);
     stubCall.addArgument(regT0);
     stubCall.addArgument(ImmPtr(ident));
     stubCall.addArgument(regT1);
     stubCall.addArgument(regT0);
     stubCall.addArgument(ImmPtr(ident));
     stubCall.addArgument(regT1);
@@ -1441,13 +538,14 @@ void JIT::emitSlow_op_put_by_id(Instruction* currentInstruction, Vector<SlowCase
 {
     unsigned baseVReg = currentInstruction[1].u.operand;
     Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
 {
     unsigned baseVReg = currentInstruction[1].u.operand;
     Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
+    unsigned direct = currentInstruction[8].u.operand;
 
     unsigned propertyAccessInstructionIndex = m_propertyAccessInstructionIndex++;
 
     linkSlowCaseIfNotJSCell(iter, baseVReg);
     linkSlowCase(iter);
 
 
     unsigned propertyAccessInstructionIndex = m_propertyAccessInstructionIndex++;
 
     linkSlowCaseIfNotJSCell(iter, baseVReg);
     linkSlowCase(iter);
 
-    JITStubCall stubCall(this, cti_op_put_by_id);
+    JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct : cti_op_put_by_id);
     stubCall.addArgument(regT0);
     stubCall.addArgument(ImmPtr(ident));
     stubCall.addArgument(regT1);
     stubCall.addArgument(regT0);
     stubCall.addArgument(ImmPtr(ident));
     stubCall.addArgument(regT1);
@@ -1501,7 +599,7 @@ void JIT::testPrototype(Structure* structure, JumpList& failureCases)
     failureCases.append(branchPtr(NotEqual, Address(regT2), regT3));
 }
 
     failureCases.append(branchPtr(NotEqual, Address(regT2), regT3));
 }
 
-void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress)
+void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
 {
     JumpList failureCases;
     // Check eax is an object of the right Structure.
 {
     JumpList failureCases;
     // Check eax is an object of the right Structure.
@@ -1510,8 +608,10 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
     testPrototype(oldStructure, failureCases);
 
     // ecx = baseObject->m_structure
     testPrototype(oldStructure, failureCases);
 
     // ecx = baseObject->m_structure
-    for (RefPtr<Structure>* it = chain->head(); *it; ++it)
-        testPrototype(it->get(), failureCases);
+    if (!direct) {
+        for (RefPtr<Structure>* it = chain->head(); *it; ++it)
+            testPrototype(it->get(), failureCases);
+    }
 
     Call callTarget;
 
 
     Call callTarget;
 
@@ -1552,7 +652,7 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
-    patchBuffer.link(failureCall, FunctionPtr(cti_op_put_by_id_fail));
+    patchBuffer.link(failureCall, FunctionPtr(direct ? cti_op_put_by_id_direct_fail : cti_op_put_by_id_fail));
 
     if (willNeedStorageRealloc) {
         ASSERT(m_calls.size() == 1);
 
     if (willNeedStorageRealloc) {
         ASSERT(m_calls.size() == 1);
@@ -1594,7 +694,6 @@ void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodC
     structure->ref();
 
     Structure* prototypeStructure = proto->structure();
     structure->ref();
 
     Structure* prototypeStructure = proto->structure();
-    ASSERT(!methodCallLinkInfo.cachedPrototypeStructure);
     methodCallLinkInfo.cachedPrototypeStructure = prototypeStructure;
     prototypeStructure->ref();
 
     methodCallLinkInfo.cachedPrototypeStructure = prototypeStructure;
     prototypeStructure->ref();
 
@@ -1606,13 +705,13 @@ void JIT::patchMethodCallProto(CodeBlock* codeBlock, MethodCallLinkInfo& methodC
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id));
 }
 
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id));
 }
 
-void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress)
+void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct)
 {
     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 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));
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
 
     int offset = sizeof(JSValue) * cachedOffset;
 
 
     int offset = sizeof(JSValue) * cachedOffset;
 
@@ -1665,7 +764,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_array_fail));
 }
 
     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)
+void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
 {
     // 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!)
 {
     // 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!)
@@ -1683,11 +782,28 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
     Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
 #endif
 
     Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
 #endif
 
-    // Checks out okay! - getDirectOffset
-    compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
-
+    bool needsStubLink = false;
+    
+    // Checks out okay!
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(ImmPtr(protoObject));
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     Jump success = jump();
     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.
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     // Use the patch information to link the failure cases back to the original slow case routine.
@@ -1698,6 +814,12 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
     // 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));
 
     // 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));
 
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
     // Track the stub we have created so that it will be deleted later.
     CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
     stubInfo->stubRoutine = entryLabel;
     // Track the stub we have created so that it will be deleted later.
     CodeLocationLabel entryLabel = patchBuffer.finalizeCodeAddendum();
     stubInfo->stubRoutine = entryLabel;
@@ -1711,14 +833,43 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
     repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list));
 }
 
     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)
+void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
 {
     Jump failureCase = checkStructure(regT0, structure);
 {
     Jump failureCase = checkStructure(regT0, structure);
-    compileGetDirectOffset(regT0, regT0, structure, cachedOffset);
+    bool needsStubLink = false;
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        if (!structure->isUsingInlineStorage()) {
+            move(regT0, regT1);
+            compileGetDirectOffset(regT1, regT1, structure, cachedOffset);
+        } else
+            compileGetDirectOffset(regT0, regT1, structure, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(regT0, regT0, structure, cachedOffset);
     Jump success = jump();
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     Jump success = jump();
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
+
     // 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)
     // 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)
@@ -1740,7 +891,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
     repatchBuffer.relink(jumpLocation, entryLabel);
 }
 
     repatchBuffer.relink(jumpLocation, entryLabel);
 }
 
-void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, size_t cachedOffset, CallFrame* callFrame)
+void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame)
 {
     // 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!)
 {
     // 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!)
@@ -1758,13 +909,38 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
     Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
 #endif
 
     Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
 #endif
 
-    // Checks out okay! - getDirectOffset
-    compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
+    // Checks out okay!
+    bool needsStubLink = false;
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(ImmPtr(protoObject));
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
 
     Jump success = jump();
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
 
     Jump success = jump();
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
+
     // 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);
     // 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);
@@ -1785,10 +961,9 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
     repatchBuffer.relink(jumpLocation, entryLabel);
 }
 
     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)
+void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructures, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame)
 {
     ASSERT(count);
 {
     ASSERT(count);
-    
     JumpList bucketsOfFail;
 
     // Check eax is an object of the right Structure.
     JumpList bucketsOfFail;
 
     // Check eax is an object of the right Structure.
@@ -1812,11 +987,36 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
 #endif
     }
     ASSERT(protoObject);
 #endif
     }
     ASSERT(protoObject);
-
-    compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
+    
+    bool needsStubLink = false;
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(ImmPtr(protoObject));
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     Jump success = jump();
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
     Jump success = jump();
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+    
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
 
     // Use the patch information to link the failure cases back to the original slow case routine.
     CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
 
     // Use the patch information to link the failure cases back to the original slow case routine.
     CodeLocationLabel lastProtoBegin = prototypeStructures->list[currentIndex - 1].stubRoutine;
@@ -1839,10 +1039,10 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
     repatchBuffer.relink(jumpLocation, entryLabel);
 }
 
     repatchBuffer.relink(jumpLocation, entryLabel);
 }
 
-void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
+void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)
 {
     ASSERT(count);
 {
     ASSERT(count);
-    
+
     JumpList bucketsOfFail;
 
     // Check eax is an object of the right Structure.
     JumpList bucketsOfFail;
 
     // Check eax is an object of the right Structure.
@@ -1866,11 +1066,36 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
     }
     ASSERT(protoObject);
 
     }
     ASSERT(protoObject);
 
-    compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
+    bool needsStubLink = false;
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        compileGetDirectOffset(protoObject, regT1, regT1, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(ImmPtr(protoObject));
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset);
     Jump success = jump();
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
     Jump success = jump();
 
     LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
 
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
+
     // Use the patch information to link the failure cases back to the original slow case routine.
     patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall));
 
     // Use the patch information to link the failure cases back to the original slow case routine.
     patchBuffer.link(bucketsOfFail, stubInfo->callReturnLocation.labelAtOffset(-patchOffsetGetByIdSlowCaseCall));
 
@@ -1894,8 +1119,8 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
 
 #endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
 
 
 #endif // !ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
 
-#endif // USE(JSVALUE32_64)
-
 } // namespace JSC
 
 #endif // ENABLE(JIT)
 } // namespace JSC
 
 #endif // ENABLE(JIT)
+
+#endif // !USE(JSVALUE32_64)
diff --git a/jit/JITPropertyAccess32_64.cpp b/jit/JITPropertyAccess32_64.cpp
new file mode 100644 (file)
index 0000000..791c88c
--- /dev/null
@@ -0,0 +1,1191 @@
+/*
+ * 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
+ * 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"
+
+#if USE(JSVALUE32_64)
+
+#include "JIT.h"
+
+#if ENABLE(JIT)
+
+#include "CodeBlock.h"
+#include "JITInlineMethods.h"
+#include "JITStubCall.h"
+#include "JSArray.h"
+#include "JSFunction.h"
+#include "JSPropertyNameIterator.h"
+#include "Interpreter.h"
+#include "LinkBuffer.h"
+#include "RepatchBuffer.h"
+#include "ResultType.h"
+#include "SamplingTool.h"
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+using namespace std;
+
+namespace JSC {
+    
+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)
+
+/* ------------------------------ 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);
+    
+    BEGIN_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
+    
+    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);
+    
+    END_UNINTERRUPTED_SEQUENCE(sequenceMethodCheck);
+    
+    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
+
+PassRefPtr<NativeExecutable> JIT::stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    JSInterfaceJIT jit;
+    JumpList failures;
+    failures.append(jit.branchPtr(NotEqual, Address(regT0), ImmPtr(globalData->jsStringVPtr)));
+    failures.append(jit.branchTest32(NonZero, Address(regT0, OBJECT_OFFSETOF(JSString, m_fiberCount))));
+    
+    // Load string length to regT1, and start the process of loading the data pointer into regT0
+    jit.load32(Address(regT0, ThunkHelpers::jsStringLengthOffset()), regT1);
+    jit.loadPtr(Address(regT0, ThunkHelpers::jsStringValueOffset()), regT0);
+    jit.loadPtr(Address(regT0, ThunkHelpers::stringImplDataOffset()), regT0);
+    
+    // Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
+    failures.append(jit.branch32(AboveOrEqual, regT2, regT1));
+    
+    // Load the character
+    jit.load16(BaseIndex(regT0, regT2, TimesTwo, 0), regT0);
+    
+    failures.append(jit.branch32(AboveOrEqual, regT0, Imm32(0x100)));
+    jit.move(ImmPtr(globalData->smallStrings.singleCharacterStrings()), regT1);
+    jit.loadPtr(BaseIndex(regT1, regT0, ScalePtr, 0), regT0);
+    jit.move(Imm32(JSValue::CellTag), regT1); // We null check regT0 on return so this is safe
+    jit.ret();
+
+    failures.link(&jit);
+    jit.move(Imm32(0), regT0);
+    jit.ret();
+    
+    LinkBuffer patchBuffer(&jit, pool);
+    return adoptRef(new NativeExecutable(patchBuffer.finalizeCode()));
+}
+
+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)));
+    
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
+    addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
+    
+    load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), regT1); // tag
+    load32(BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0])), regT0); // payload
+    addSlowCase(branch32(Equal, regT1, Imm32(JSValue::EmptyValueTag)));
+    
+    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;
+    
+    linkSlowCase(iter); // property int32 check
+    linkSlowCaseIfNotJSCell(iter, base); // base cell check
+
+    Jump nonCell = jump();
+    linkSlowCase(iter); // base array check
+    Jump notString = branchPtr(NotEqual, Address(regT0), ImmPtr(m_globalData->jsStringVPtr));
+    emitNakedCall(m_globalData->getThunk(stringGetByValStubGenerator)->generatedJITCode().addressForCall());
+    Jump failed = branchTestPtr(Zero, regT0);
+    emitStore(dst, regT1, regT0);
+    emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_get_by_val));
+    failed.link(this);
+    notString.link(this);
+    nonCell.link(this);
+
+    linkSlowCase(iter); // vector length check
+    linkSlowCase(iter); // empty value
+    
+    JITStubCall stubCall(this, cti_op_get_by_val);
+    stubCall.addArgument(base);
+    stubCall.addArgument(property);
+    stubCall.call(dst);
+}
+
+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)));
+    addSlowCase(branch32(AboveOrEqual, regT2, Address(regT0, OBJECT_OFFSETOF(JSArray, m_vectorLength))));
+    
+    loadPtr(Address(regT0, OBJECT_OFFSETOF(JSArray, m_storage)), regT3);
+    
+    Jump empty = branch32(Equal, BaseIndex(regT3, regT2, TimesEight, OBJECT_OFFSETOF(ArrayStorage, m_vector[0]) + 4), Imm32(JSValue::EmptyValueTag));
+    
+    Label storeResult(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
+    Jump end = jump();
+    
+    empty.link(this);
+    add32(Imm32(1), Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_numValuesInVector)));
+    branch32(Below, regT2, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length))).linkTo(storeResult, this);
+    
+    add32(Imm32(1), regT2, regT0);
+    store32(regT0, Address(regT3, OBJECT_OFFSETOF(ArrayStorage, m_length)));
+    jump().linkTo(storeResult, this);
+    
+    end.link(this);
+}
+
+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
+    linkSlowCase(iter); // in vector check
+    
+    JITStubCall stubPutByValCall(this, cti_op_put_by_val);
+    stubPutByValCall.addArgument(base);
+    stubPutByValCall.addArgument(property);
+    stubPutByValCall.addArgument(value);
+    stubPutByValCall.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.
+    
+    BEGIN_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
+    
+    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);
+    
+    END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdHotPath);
+}
+
+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);
+    
+    BEGIN_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
+    
+#ifndef NDEBUG
+    Label coldPathBegin(this);
+#endif
+    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);
+    
+    END_UNINTERRUPTED_SEQUENCE(sequenceGetByIdSlowCase);
+    
+    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);
+    
+    BEGIN_UNINTERRUPTED_SEQUENCE(sequencePutById);
+    
+    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
+    
+    END_UNINTERRUPTED_SEQUENCE(sequencePutById);
+    
+    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;
+    int direct = currentInstruction[8].u.operand;
+
+    linkSlowCaseIfNotJSCell(iter, base);
+    linkSlowCase(iter);
+    
+    JITStubCall stubCall(this, direct ? cti_op_put_by_id_direct : 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::testPrototype(Structure* structure, JumpList& failureCases)
+{
+    if (structure->m_prototype.isNull())
+        return;
+    
+    failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(structure->m_prototype)->m_structure), ImmPtr(asCell(structure->m_prototype)->m_structure)));
+}
+
+void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
+{
+    // 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)));
+    failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure)));
+    testPrototype(oldStructure, failureCases);
+    
+    if (!direct) {
+        // Verify that nothing in the prototype chain has a setter for this property. 
+        for (RefPtr<Structure>* it = chain->head(); *it; ++it)
+            testPrototype(it->get(), failureCases);
+    }
+
+    // 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, OBJECT_OFFSETOF(struct JITStackFrame, args[2]) + sizeof(void*)), regT3);
+    load32(Address(stackPointerRegister, OBJECT_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(direct ? cti_op_put_by_id_direct_fail : 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, ReturnAddressPtr returnAddress)
+{
+    RepatchBuffer repatchBuffer(codeBlock);
+    
+    ASSERT(!methodCallLinkInfo.cachedStructure);
+    methodCallLinkInfo.cachedStructure = structure;
+    structure->ref();
+    
+    Structure* prototypeStructure = proto->structure();
+    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);
+    
+    repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id));
+}
+
+void JIT::patchPutByIdReplace(CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, size_t cachedOffset, ReturnAddressPtr returnAddress, bool direct)
+{
+    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(direct ? cti_op_put_by_id_direct_generic : 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, const Identifier& ident, const PropertySlot& slot, 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 CPU(X86_64)
+    move(ImmPtr(prototypeStructure), regT3);
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
+#else
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+#endif
+    bool needsStubLink = false;
+    // Checks out okay!
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(ImmPtr(protoObject));
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        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));
+
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
+
+    // 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, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset)
+{
+    // regT0 holds a JSCell*
+    Jump failureCase = checkStructure(regT0, structure);
+    bool needsStubLink = false;
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        if (!structure->isUsingInlineStorage()) {
+            move(regT0, regT1);
+            compileGetDirectOffset(regT1, regT2, regT1, structure, cachedOffset);
+        } else
+            compileGetDirectOffset(regT0, regT2, regT1, structure, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(regT0, regT1, regT0, structure, cachedOffset);
+
+    Jump success = jump();
+    
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }    
+    // 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, const Identifier& ident, const PropertySlot& slot, 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 CPU(X86_64)
+    move(ImmPtr(prototypeStructure), regT3);
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), regT3);
+#else
+    Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
+#endif
+    
+    bool needsStubLink = false;
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(ImmPtr(protoObject));
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+    
+    Jump success = jump();
+    
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
+    // 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, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, 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 CPU(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);
+    
+    bool needsStubLink = false;
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(ImmPtr(protoObject));
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+
+    Jump success = jump();
+    
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
+    // 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, const Identifier& ident, const PropertySlot& slot, 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 CPU(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);
+    
+    bool needsStubLink = false;
+    if (slot.cachedPropertyType() == PropertySlot::Getter) {
+        needsStubLink = true;
+        compileGetDirectOffset(protoObject, regT2, regT2, regT1, cachedOffset);
+        JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);
+        stubCall.addArgument(regT1);
+        stubCall.addArgument(regT0);
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else if (slot.cachedPropertyType() == PropertySlot::Custom) {
+        needsStubLink = true;
+        JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);
+        stubCall.addArgument(ImmPtr(protoObject));
+        stubCall.addArgument(ImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));
+        stubCall.addArgument(ImmPtr(const_cast<Identifier*>(&ident)));
+        stubCall.addArgument(ImmPtr(stubInfo->callReturnLocation.executableAddress()));
+        stubCall.call();
+    } else
+        compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+    Jump success = jump();
+    
+    LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
+    if (needsStubLink) {
+        for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {
+            if (iter->to)
+                patchBuffer.link(iter->from, FunctionPtr(iter->to));
+        }
+    }
+    // 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)
+
+void JIT::compileGetDirectOffset(RegisterID base, RegisterID resultTag, RegisterID resultPayload, RegisterID structure, RegisterID offset)
+{
+    ASSERT(sizeof(((Structure*)0)->m_propertyStorageCapacity) == sizeof(int32_t));
+    ASSERT(sizeof(JSObject::inlineStorageCapacity) == sizeof(int32_t));
+    ASSERT(sizeof(JSValue) == 8);
+    
+    Jump notUsingInlineStorage = branch32(NotEqual, Address(structure, OBJECT_OFFSETOF(Structure, m_propertyStorageCapacity)), Imm32(JSObject::inlineStorageCapacity));
+    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
+    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSObject, m_inlineStorage)+OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
+    Jump finishedLoad = jump();
+    notUsingInlineStorage.link(this);
+    loadPtr(Address(base, OBJECT_OFFSETOF(JSObject, m_externalStorage)), base);
+    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload);
+    loadPtr(BaseIndex(base, offset, TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag);
+    finishedLoad.link(this);
+}
+
+void JIT::emit_op_get_by_pname(Instruction* currentInstruction)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned base = currentInstruction[2].u.operand;
+    unsigned property = currentInstruction[3].u.operand;
+    unsigned expected = currentInstruction[4].u.operand;
+    unsigned iter = currentInstruction[5].u.operand;
+    unsigned i = currentInstruction[6].u.operand;
+    
+    emitLoad2(property, regT1, regT0, base, regT3, regT2);
+    emitJumpSlowCaseIfNotJSCell(property, regT1);
+    addSlowCase(branchPtr(NotEqual, regT0, payloadFor(expected)));
+    // Property registers are now available as the property is known
+    emitJumpSlowCaseIfNotJSCell(base, regT3);
+    emitLoadPayload(iter, regT1);
+    
+    // Test base's structure
+    loadPtr(Address(regT2, OBJECT_OFFSETOF(JSCell, m_structure)), regT0);
+    addSlowCase(branchPtr(NotEqual, regT0, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_cachedStructure))));
+    load32(addressFor(i), regT3);
+    sub32(Imm32(1), regT3);
+    addSlowCase(branch32(AboveOrEqual, regT3, Address(regT1, OBJECT_OFFSETOF(JSPropertyNameIterator, m_numCacheableSlots))));
+    compileGetDirectOffset(regT2, regT1, regT0, regT0, regT3);    
+    
+    emitStore(dst, regT1, regT0);
+    map(m_bytecodeIndex + OPCODE_LENGTH(op_get_by_pname), dst, regT1, regT0);
+}
+
+void JIT::emitSlow_op_get_by_pname(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
+{
+    unsigned dst = currentInstruction[1].u.operand;
+    unsigned base = currentInstruction[2].u.operand;
+    unsigned property = currentInstruction[3].u.operand;
+    
+    linkSlowCaseIfNotJSCell(iter, property);
+    linkSlowCase(iter);
+    linkSlowCaseIfNotJSCell(iter, base);
+    linkSlowCase(iter);
+    linkSlowCase(iter);
+    
+    JITStubCall stubCall(this, cti_op_get_by_val);
+    stubCall.addArgument(base);
+    stubCall.addArgument(property);
+    stubCall.call(dst);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(JIT)
+
+#endif // ENABLE(JSVALUE32_64)
+
index cfbd7dc68befd618cae23fba2631f787c6c19c80..70d289350bd7674681c8331ed33b20a99f0625dc 100644 (file)
@@ -116,13 +116,15 @@ namespace JSC {
             m_jit->poke(argument, m_stackIndex);
             m_stackIndex += stackIndexStep;
         }
             m_jit->poke(argument, m_stackIndex);
             m_stackIndex += stackIndexStep;
         }
-
+        
+#if USE(JSVALUE32_64)
         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(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;
         }
+#endif
 
         void addArgument(JIT::RegisterID tag, JIT::RegisterID payload)
         {
 
         void addArgument(JIT::RegisterID tag, JIT::RegisterID payload)
         {
index 4706eb148a8ed4d8ca763cd299a40f4801c8ae59..a104faf6605b677c477e05b407dfcd24f65905b4 100644 (file)
@@ -38,6 +38,7 @@
 #include "Collector.h"
 #include "Debugger.h"
 #include "ExceptionHelpers.h"
 #include "Collector.h"
 #include "Debugger.h"
 #include "ExceptionHelpers.h"
+#include "GetterSetter.h"
 #include "GlobalEvalFunction.h"
 #include "JIT.h"
 #include "JSActivation.h"
 #include "GlobalEvalFunction.h"
 #include "JIT.h"
 #include "JSActivation.h"
@@ -238,99 +239,20 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
 #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7."
 #endif
 
 #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7."
 #endif
 
-asm volatile (
-".text" "\n"
-".align 2" "\n"
-".globl " SYMBOL_STRING(ctiTrampoline) "\n"
-HIDE_SYMBOL(ctiTrampoline) "\n"
-".thumb" "\n"
-".thumb_func " THUMB_FUNC_PARAM(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"
-HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
-".thumb" "\n"
-".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n"
-SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
-    "cpy r0, sp" "\n"
-    "bl " SYMBOL_STRING_RELOCATION(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 " THUMB_FUNC_PARAM(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"
-);
+#define THUNK_RETURN_ADDRESS_OFFSET      0x3C
+#define PRESERVED_RETURN_ADDRESS_OFFSET  0x40
+#define PRESERVED_R4_OFFSET              0x44
+#define PRESERVED_R5_OFFSET              0x48
+#define PRESERVED_R6_OFFSET              0x4C
+#define REGISTER_FILE_OFFSET             0x50
+#define CALLFRAME_OFFSET                 0x54
+#define EXCEPTION_OFFSET                 0x58
+#define ENABLE_PROFILER_REFERENCE_OFFSET 0x60
 
 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
 
 
 #elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
 
-asm volatile (
-".globl " SYMBOL_STRING(ctiTrampoline) "\n"
-SYMBOL_STRING(ctiTrampoline) ":" "\n"
-    "stmdb sp!, {r1-r3}" "\n"
-    "stmdb sp!, {r4-r8, lr}" "\n"
-    "sub sp, sp, #68" "\n"
-    "mov r4, r2" "\n"
-    "mov r5, #512" "\n"
-    // r0 contains the code
-    "mov lr, pc" "\n"
-    "mov pc, r0" "\n"
-    "add sp, sp, #68" "\n"
-    "ldmia sp!, {r4-r8, lr}" "\n"
-    "add sp, sp, #12" "\n"
-    "mov pc, lr" "\n"
-);
-
-asm volatile (
-".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
-    "mov r0, sp" "\n"
-    "bl " SYMBOL_STRING(cti_vm_throw) "\n"
-
-// Both has the same return sequence
-".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
-SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
-    "add sp, sp, #68" "\n"
-    "ldmia sp!, {r4-r8, lr}" "\n"
-    "add sp, sp, #12" "\n"
-    "mov pc, lr" "\n"
-);
+#define THUNK_RETURN_ADDRESS_OFFSET 64
+#define PRESERVEDR4_OFFSET          68
 
 #elif COMPILER(MSVC) && CPU(X86)
 
 
 #elif COMPILER(MSVC) && CPU(X86)
 
@@ -543,106 +465,122 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
 #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7."
 #endif
 
 #error "JIT_STUB_ARGUMENT_VA_LIST not supported on ARMv7."
 #endif
 
-asm volatile (
+#define THUNK_RETURN_ADDRESS_OFFSET      0x1C
+#define PRESERVED_RETURN_ADDRESS_OFFSET  0x20
+#define PRESERVED_R4_OFFSET              0x24
+#define PRESERVED_R5_OFFSET              0x28
+#define PRESERVED_R6_OFFSET              0x2C
+#define REGISTER_FILE_OFFSET             0x30
+#define CALLFRAME_OFFSET                 0x34
+#define EXCEPTION_OFFSET                 0x38
+#define ENABLE_PROFILER_REFERENCE_OFFSET 0x40
+
+#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
+
+#define THUNK_RETURN_ADDRESS_OFFSET 32
+#define PRESERVEDR4_OFFSET          36
+
+#elif CPU(MIPS)
+
+#if USE(JIT_STUB_ARGUMENT_VA_LIST)
+#error "JIT_STUB_ARGUMENT_VA_LIST not supported on MIPS."
+#endif
+
+asm volatile(
 ".text" "\n"
 ".align 2" "\n"
 ".text" "\n"
 ".align 2" "\n"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\n"
 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
 ".globl " SYMBOL_STRING(ctiTrampoline) "\n"
-HIDE_SYMBOL(ctiTrampoline) "\n"
-".thumb" "\n"
-".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n"
+".ent " SYMBOL_STRING(ctiTrampoline) "\n"
 SYMBOL_STRING(ctiTrampoline) ":" "\n"
 SYMBOL_STRING(ctiTrampoline) ":" "\n"
-    "sub sp, sp, #0x40" "\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, #0x40" "\n"
-    "bx lr" "\n"
+    "addiu $29,$29,-72" "\n"
+    "sw    $31,44($29)" "\n"
+    "sw    $18,40($29)" "\n"
+    "sw    $17,36($29)" "\n"
+    "sw    $16,32($29)" "\n"
+#if WTF_MIPS_PIC
+    "sw    $28,28($29)" "\n"
+#endif
+    "move  $16,$6       # set callFrameRegister" "\n"
+    "li    $17,512      # set timeoutCheckRegister" "\n"
+    "move  $25,$4       # move executableAddress to t9" "\n"
+    "sw    $5,52($29)   # store registerFile to current stack" "\n"
+    "sw    $6,56($29)   # store callFrame to curent stack" "\n"
+    "sw    $7,60($29)   # store exception to current stack" "\n"
+    "lw    $8,88($29)   # load enableProfilerReference from previous stack" "\n"
+    "lw    $9,92($29)   # load globalData from previous stack" "\n"
+    "sw    $8,64($29)   # store enableProfilerReference to current stack" "\n"
+    "jalr  $25" "\n"
+    "sw    $9,68($29)   # store globalData to current stack" "\n"
+    "lw    $16,32($29)" "\n"
+    "lw    $17,36($29)" "\n"
+    "lw    $18,40($29)" "\n"
+    "lw    $31,44($29)" "\n"
+    "jr    $31" "\n"
+    "addiu $29,$29,72" "\n"
+".set reorder" "\n"
+".set macro" "\n"
+".end " SYMBOL_STRING(ctiTrampoline) "\n"
 );
 
 );
 
-asm volatile (
+asm volatile(
 ".text" "\n"
 ".align 2" "\n"
 ".text" "\n"
 ".align 2" "\n"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\n"
 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
 ".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
-".thumb" "\n"
-".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n"
+".ent " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
 SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
-    "cpy r0, sp" "\n"
-    "bl " SYMBOL_STRING_RELOCATION(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, #0x40" "\n"
-    "bx lr" "\n"
+#if WTF_MIPS_PIC
+    "lw    $28,28($29)" "\n"
+".set macro" "\n"
+    "la    $25," SYMBOL_STRING(cti_vm_throw) "\n"
+".set nomacro" "\n"
+    "bal " SYMBOL_STRING(cti_vm_throw) "\n"
+    "move  $4,$29" "\n"
+#else
+    "jal " SYMBOL_STRING(cti_vm_throw) "\n"
+    "move  $4,$29" "\n"
+#endif
+    "lw    $16,32($29)" "\n"
+    "lw    $17,36($29)" "\n"
+    "lw    $18,40($29)" "\n"
+    "lw    $31,44($29)" "\n"
+    "jr    $31" "\n"
+    "addiu $29,$29,72" "\n"
+".set reorder" "\n"
+".set macro" "\n"
+".end " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
 );
 
 );
 
-asm volatile (
+asm volatile(
 ".text" "\n"
 ".align 2" "\n"
 ".text" "\n"
 ".align 2" "\n"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\n"
 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 ".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
-HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
-".thumb" "\n"
-".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n"
+".ent " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 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(GCC) && CPU(ARM_TRADITIONAL)
-
-asm volatile (
-".text\n"
-".globl " SYMBOL_STRING(ctiTrampoline) "\n"
-HIDE_SYMBOL(ctiTrampoline) "\n"
-SYMBOL_STRING(ctiTrampoline) ":" "\n"
-    "stmdb sp!, {r1-r3}" "\n"
-    "stmdb sp!, {r4-r8, lr}" "\n"
-    "sub sp, sp, #36" "\n"
-    "mov r4, r2" "\n"
-    "mov r5, #512" "\n"
-    "mov lr, pc" "\n"
-    "mov pc, r0" "\n"
-    "add sp, sp, #36" "\n"
-    "ldmia sp!, {r4-r8, lr}" "\n"
-    "add sp, sp, #12" "\n"
-    "mov pc, lr" "\n"
-);
-
-asm volatile (
-".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
-HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
-SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
-    "mov r0, sp" "\n"
-    "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
-
-// Both has the same return sequence
-".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
-HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
-SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
-    "add sp, sp, #36" "\n"
-    "ldmia sp!, {r4-r8, lr}" "\n"
-    "add sp, sp, #12" "\n"
-    "mov pc, lr" "\n"
+    "lw    $16,32($29)" "\n"
+    "lw    $17,36($29)" "\n"
+    "lw    $18,40($29)" "\n"
+    "lw    $31,44($29)" "\n"
+    "jr    $31" "\n"
+    "addiu $29,$29,72" "\n"
+".set reorder" "\n"
+".set macro" "\n"
+".end " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
 );
 
 #elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL)
 
 );
 
 #elif COMPILER(RVCT) && CPU(ARM_TRADITIONAL)
 
+#define THUNK_RETURN_ADDRESS_OFFSET 32
+#define PRESERVEDR4_OFFSET          36
+
 __asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, JSValue*, Profiler**, JSGlobalData*)
 {
     ARM
 __asm EncodedJSValue ctiTrampoline(void*, RegisterFile*, CallFrame*, JSValue*, Profiler**, JSGlobalData*)
 {
     ARM
@@ -749,6 +687,108 @@ extern "C" {
 
 #endif // USE(JSVALUE32_64)
 
 
 #endif // USE(JSVALUE32_64)
 
+#if COMPILER(GCC) && CPU(ARM_THUMB2)
+
+asm volatile(
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
+".thumb" "\n"
+".thumb_func " THUMB_FUNC_PARAM(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+    "sub sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n"
+    "str lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n"
+    "str r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n"
+    "str r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n"
+    "str r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n"
+    "str r1, [sp, #" STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "]" "\n"
+    "str r2, [sp, #" STRINGIZE_VALUE_OF(CALLFRAME_OFFSET) "]" "\n"
+    "str r3, [sp, #" STRINGIZE_VALUE_OF(EXCEPTION_OFFSET) "]" "\n"
+    "cpy r5, r2" "\n"
+    "mov r6, #512" "\n"
+    "blx r0" "\n"
+    "ldr r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n"
+    "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n"
+    "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n"
+    "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n"
+    "add sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n"
+    "bx lr" "\n"
+);
+
+asm volatile(
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
+".thumb" "\n"
+".thumb_func " THUMB_FUNC_PARAM(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+    "cpy r0, sp" "\n"
+    "bl " SYMBOL_STRING_RELOCATION(cti_vm_throw) "\n"
+    "ldr r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n"
+    "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n"
+    "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n"
+    "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n"
+    "add sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n"
+    "bx lr" "\n"
+);
+
+asm volatile(
+".text" "\n"
+".align 2" "\n"
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
+".thumb" "\n"
+".thumb_func " THUMB_FUNC_PARAM(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+    "ldr r6, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R6_OFFSET) "]" "\n"
+    "ldr r5, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R5_OFFSET) "]" "\n"
+    "ldr r4, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_R4_OFFSET) "]" "\n"
+    "ldr lr, [sp, #" STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "]" "\n"
+    "add sp, sp, #" STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "\n"
+    "bx lr" "\n"
+);
+
+#elif COMPILER(GCC) && CPU(ARM_TRADITIONAL)
+
+asm volatile(
+".globl " SYMBOL_STRING(ctiTrampoline) "\n"
+HIDE_SYMBOL(ctiTrampoline) "\n"
+SYMBOL_STRING(ctiTrampoline) ":" "\n"
+    "stmdb sp!, {r1-r3}" "\n"
+    "stmdb sp!, {r4-r8, lr}" "\n"
+    "sub sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n"
+    "mov r4, r2" "\n"
+    "mov r5, #512" "\n"
+    // r0 contains the code
+    "mov lr, pc" "\n"
+    "mov pc, r0" "\n"
+    "add sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n"
+    "ldmia sp!, {r4-r8, lr}" "\n"
+    "add sp, sp, #12" "\n"
+    "mov pc, lr" "\n"
+);
+
+asm volatile(
+".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
+HIDE_SYMBOL(ctiVMThrowTrampoline) "\n"
+SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
+    "mov r0, sp" "\n"
+    "bl " SYMBOL_STRING(cti_vm_throw) "\n"
+
+// Both has the same return sequence
+".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
+HIDE_SYMBOL(ctiOpThrowNotCaught) "\n"
+SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
+    "add sp, sp, #" STRINGIZE_VALUE_OF(PRESERVEDR4_OFFSET) "\n"
+    "ldmia sp!, {r4-r8, lr}" "\n"
+    "add sp, sp, #12" "\n"
+    "mov pc, lr" "\n"
+);
+
+#endif
+
 #if ENABLE(OPCODE_SAMPLING)
     #define CTI_SAMPLER stackFrame.globalData->interpreter->sampler()
 #else
 #if ENABLE(OPCODE_SAMPLING)
     #define CTI_SAMPLER stackFrame.globalData->interpreter->sampler()
 #else
@@ -757,30 +797,54 @@ extern "C" {
 
 JITThunks::JITThunks(JSGlobalData* globalData)
 {
 
 JITThunks::JITThunks(JSGlobalData* globalData)
 {
-    JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_ctiStringLengthTrampoline, &m_ctiVirtualCallLink, &m_ctiVirtualCall, &m_ctiNativeCallThunk);
+    JIT::compileCTIMachineTrampolines(globalData, &m_executablePool, &m_trampolineStructure);
 
 #if CPU(ARM_THUMB2)
     // 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.
 
 #if CPU(ARM_THUMB2)
     // 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);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == PRESERVED_RETURN_ADDRESS_OFFSET);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR4) == PRESERVED_R4_OFFSET);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR5) == PRESERVED_R5_OFFSET);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR6) == PRESERVED_R6_OFFSET);
+
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == REGISTER_FILE_OFFSET);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == CALLFRAME_OFFSET);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == EXCEPTION_OFFSET);
     // The fifth argument is the first item already on the stack.
     // The fifth argument is the first item already on the stack.
-    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == 0x40);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == ENABLE_PROFILER_REFERENCE_OFFSET);
+
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
+
+#elif CPU(ARM_TRADITIONAL)
+
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedR4) == PRESERVEDR4_OFFSET);
+
+
+#elif CPU(MIPS)
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedGP) == 28);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS0) == 32);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS1) == 36);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedS2) == 40);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, preservedReturnAddress) == 44);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == 48);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, registerFile) == 52);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, callFrame) == 56);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, exception) == 60);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, enabledProfilerReference) == 64);
+    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, globalData) == 68);
 
 
-    ASSERT(OBJECT_OFFSETOF(struct JITStackFrame, thunkReturnAddress) == 0x1C);
 #endif
 }
 
 #endif
 }
 
+JITThunks::~JITThunks()
+{
+}
+
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
 
 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
 
-NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo)
+NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot& slot, StructureStubInfo* stubInfo, bool direct)
 {
     // The interpreter checks for recursion here; I do not believe this can occur in CTI.
 
 {
     // The interpreter checks for recursion here; I do not believe this can occur in CTI.
 
@@ -789,7 +853,7 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
 
     // Uncacheable: give up.
     if (!slot.isCacheable()) {
 
     // Uncacheable: give up.
     if (!slot.isCacheable()) {
-        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
         return;
     }
     
         return;
     }
     
@@ -797,13 +861,13 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
     Structure* structure = baseCell->structure();
 
     if (structure->isUncacheableDictionary()) {
     Structure* structure = baseCell->structure();
 
     if (structure->isUncacheableDictionary()) {
-        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
         return;
     }
 
     // If baseCell != base, then baseCell must be a proxy for another object.
     if (baseCell != slot.base()) {
         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));
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
         return;
     }
 
         return;
     }
 
@@ -812,7 +876,7 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
     // Structure transition, cache transition info
     if (slot.type() == PutPropertySlot::NewProperty) {
         if (structure->isDictionary()) {
     // Structure transition, cache transition info
     if (slot.type() == PutPropertySlot::NewProperty) {
         if (structure->isDictionary()) {
-            ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_put_by_id_generic));
+            ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(direct ? cti_op_put_by_id_direct_generic : cti_op_put_by_id_generic));
             return;
         }
 
             return;
         }
 
@@ -821,13 +885,13 @@ NEVER_INLINE void JITThunks::tryCachePutByID(CallFrame* callFrame, CodeBlock* co
 
         StructureChain* prototypeChain = structure->prototypeChain(callFrame);
         stubInfo->initPutByIdTransition(structure->previousID(), structure, prototypeChain);
 
         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);
+        JIT::compilePutByIdTransition(callFrame->scopeChain()->globalData, codeBlock, stubInfo, structure->previousID(), structure, slot.cachedOffset(), prototypeChain, returnAddress, direct);
         return;
     }
     
     stubInfo->initPutByIdReplace(structure);
 
         return;
     }
     
     stubInfo->initPutByIdReplace(structure);
 
-    JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
+    JIT::patchPutByIdReplace(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress, direct);
 }
 
 NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
 }
 
 NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot& slot, StructureStubInfo* stubInfo)
@@ -851,7 +915,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
     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.
     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());
+        ctiPatchCallByReturnAddress(codeBlock, returnAddress, globalData->jitStubs->ctiStringLengthTrampoline());
         return;
     }
 
         return;
     }
 
@@ -874,8 +938,10 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
     if (slot.slotBase() == baseValue) {
         // set this up, so derefStructures can do it's job.
         stubInfo->initGetByIdSelf(structure);
     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);
+        if (slot.cachedPropertyType() != PropertySlot::Value)
+            ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_self_fail));
+        else
+            JIT::patchGetByIdSelf(codeBlock, stubInfo, structure, slot.cachedOffset(), returnAddress);
         return;
     }
 
         return;
     }
 
@@ -901,7 +967,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
 
         ASSERT(!structure->isDictionary());
         ASSERT(!slotBaseObject->structure()->isDictionary());
 
         ASSERT(!structure->isDictionary());
         ASSERT(!slotBaseObject->structure()->isDictionary());
-        JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), offset, returnAddress);
+        JIT::compileGetByIdProto(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, slotBaseObject->structure(), propertyName, slot, offset, returnAddress);
         return;
     }
 
         return;
     }
 
@@ -914,7 +980,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
 
     StructureChain* prototypeChain = structure->prototypeChain(callFrame);
     stubInfo->initGetByIdChain(structure, prototypeChain);
 
     StructureChain* prototypeChain = structure->prototypeChain(callFrame);
     stubInfo->initGetByIdChain(structure, prototypeChain);
-    JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, offset, returnAddress);
+    JIT::compileGetByIdChain(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, structure, prototypeChain, count, propertyName, slot, offset, returnAddress);
 }
 
 #endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
 }
 
 #endif // ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS)
@@ -1024,22 +1090,73 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
         ".thumb" "\n" \
         ".thumb_func " THUMB_FUNC_PARAM(cti_##op) "\n" \
         SYMBOL_STRING(cti_##op) ":" "\n" \
         ".thumb" "\n" \
         ".thumb_func " THUMB_FUNC_PARAM(cti_##op) "\n" \
         SYMBOL_STRING(cti_##op) ":" "\n" \
-        "str lr, [sp, #0x1c]" "\n" \
+        "str lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
         "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \
         "bl " SYMBOL_STRING(JITStubThunked_##op) "\n" \
-        "ldr lr, [sp, #0x1c]" "\n" \
+        "ldr lr, [sp, #" STRINGIZE_VALUE_OF(THUNK_RETURN_ADDRESS_OFFSET) "]" "\n" \
         "bx lr" "\n" \
         ); \
     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \
 
         "bx lr" "\n" \
         ); \
     rtype JITStubThunked_##op(STUB_ARGS_DECLARATION) \
 
-#elif CPU(ARM_TRADITIONAL) && COMPILER(GCC)
+#elif CPU(MIPS)
+#if WTF_MIPS_PIC
+#define DEFINE_STUB_FUNCTION(rtype, op) \
+    extern "C" { \
+        rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
+    }; \
+    asm volatile( \
+        ".text" "\n" \
+        ".align 2" "\n" \
+        ".set noreorder" "\n" \
+        ".set nomacro" "\n" \
+        ".set nomips16" "\n" \
+        ".globl " SYMBOL_STRING(cti_##op) "\n" \
+        ".ent " SYMBOL_STRING(cti_##op) "\n" \
+        SYMBOL_STRING(cti_##op) ":" "\n" \
+        "lw    $28,28($29)" "\n" \
+        "sw    $31,48($29)" "\n" \
+        ".set macro" "\n" \
+        "la    $25," SYMBOL_STRING(JITStubThunked_##op) "\n" \
+        ".set nomacro" "\n" \
+        "bal " SYMBOL_STRING(JITStubThunked_##op) "\n" \
+        "nop" "\n" \
+        "lw    $31,48($29)" "\n" \
+        "jr    $31" "\n" \
+        "nop" "\n" \
+        ".set reorder" "\n" \
+        ".set macro" "\n" \
+        ".end " SYMBOL_STRING(cti_##op) "\n" \
+        ); \
+    rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
+
+#else // WTF_MIPS_PIC
+#define DEFINE_STUB_FUNCTION(rtype, op) \
+    extern "C" { \
+        rtype JITStubThunked_##op(STUB_ARGS_DECLARATION); \
+    }; \
+    asm volatile( \
+        ".text" "\n" \
+        ".align 2" "\n" \
+        ".set noreorder" "\n" \
+        ".set nomacro" "\n" \
+        ".set nomips16" "\n" \
+        ".globl " SYMBOL_STRING(cti_##op) "\n" \
+        ".ent " SYMBOL_STRING(cti_##op) "\n" \
+        SYMBOL_STRING(cti_##op) ":" "\n" \
+        "sw    $31,48($29)" "\n" \
+        "jal " SYMBOL_STRING(JITStubThunked_##op) "\n" \
+        "nop" "\n" \
+        "lw    $31,48($29)" "\n" \
+        "jr    $31" "\n" \
+        "nop" "\n" \
+        ".set reorder" "\n" \
+        ".set macro" "\n" \
+        ".end " SYMBOL_STRING(cti_##op) "\n" \
+        ); \
+    rtype JITStubThunked_##op(STUB_ARGS_DECLARATION)
 
 
-#if USE(JSVALUE32_64)
-#define THUNK_RETURN_ADDRESS_OFFSET 64
-#else
-#define THUNK_RETURN_ADDRESS_OFFSET 32
 #endif
 
 #endif
 
-COMPILE_ASSERT(offsetof(struct JITStackFrame, thunkReturnAddress) == THUNK_RETURN_ADDRESS_OFFSET, JITStackFrame_thunkReturnAddress_offset_mismatch);
+#elif CPU(ARM_TRADITIONAL) && COMPILER(GCC)
 
 #define DEFINE_STUB_FUNCTION(rtype, op) \
     extern "C" { \
 
 #define DEFINE_STUB_FUNCTION(rtype, op) \
     extern "C" { \
@@ -1070,9 +1187,9 @@ RVCT(__asm #rtype# cti_#op#(STUB_ARGS_DECLARATION))
 RVCT({)
 RVCT(    ARM)
 RVCT(    IMPORT JITStubThunked_#op#)
 RVCT({)
 RVCT(    ARM)
 RVCT(    IMPORT JITStubThunked_#op#)
-RVCT(    str lr, [sp, #32])
+RVCT(    str lr, [sp, ##offset#])
 RVCT(    bl JITStubThunked_#op#)
 RVCT(    bl JITStubThunked_#op#)
-RVCT(    ldr lr, [sp, #32])
+RVCT(    ldr lr, [sp, ##offset#])
 RVCT(    bx lr)
 RVCT(})
 RVCT()
 RVCT(    bx lr)
 RVCT(})
 RVCT()
@@ -1147,15 +1264,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_inc)
 DEFINE_STUB_FUNCTION(int, timeout_check)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
 DEFINE_STUB_FUNCTION(int, timeout_check)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
-    
+
     JSGlobalData* globalData = stackFrame.globalData;
     TimeoutChecker& timeoutChecker = globalData->timeoutChecker;
 
     JSGlobalData* globalData = stackFrame.globalData;
     TimeoutChecker& timeoutChecker = globalData->timeoutChecker;
 
-    if (timeoutChecker.didTimeOut(stackFrame.callFrame)) {
+    if (globalData->terminator.shouldTerminate()) {
+        globalData->exception = createTerminatedExecutionException(globalData);
+        VM_THROW_EXCEPTION_AT_END();
+    } else if (timeoutChecker.didTimeOut(stackFrame.callFrame)) {
         globalData->exception = createInterruptedExecutionException(globalData);
         VM_THROW_EXCEPTION_AT_END();
     }
         globalData->exception = createInterruptedExecutionException(globalData);
         VM_THROW_EXCEPTION_AT_END();
     }
-    
+
     return timeoutChecker.ticksUntilNextCheck();
 }
 
     return timeoutChecker.ticksUntilNextCheck();
 }
 
@@ -1202,6 +1322,15 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_generic)
     CHECK_FOR_EXCEPTION_AT_END();
 }
 
     CHECK_FOR_EXCEPTION_AT_END();
 }
 
+DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_generic)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    
+    PutPropertySlot slot;
+    stackFrame.args[0].jsValue().putDirect(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);
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_generic)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
@@ -1224,17 +1353,36 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id)
     STUB_INIT_STACK_FRAME(stackFrame);
     CallFrame* callFrame = stackFrame.callFrame;
     Identifier& ident = stackFrame.args[1].identifier();
     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);
     PutPropertySlot slot;
     stackFrame.args[0].jsValue().put(callFrame, ident, stackFrame.args[2].jsValue(), slot);
-
+    
     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
     if (!stubInfo->seenOnce())
         stubInfo->setSeen();
     else
     CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
     StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
     if (!stubInfo->seenOnce())
         stubInfo->setSeen();
     else
-        JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo);
+        JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, false);
+    
+    CHECK_FOR_EXCEPTION_AT_END();
+}
 
 
+DEFINE_STUB_FUNCTION(void, op_put_by_id_direct)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+    
+    PutPropertySlot slot;
+    stackFrame.args[0].jsValue().putDirect(callFrame, ident, stackFrame.args[2].jsValue(), slot);
+    
+    CodeBlock* codeBlock = stackFrame.callFrame->codeBlock();
+    StructureStubInfo* stubInfo = &codeBlock->getStubInfo(STUB_RETURN_ADDRESS);
+    if (!stubInfo->seenOnce())
+        stubInfo->setSeen();
+    else
+        JITThunks::tryCachePutByID(callFrame, codeBlock, STUB_RETURN_ADDRESS, stackFrame.args[0].jsValue(), slot, stubInfo, true);
+    
     CHECK_FOR_EXCEPTION_AT_END();
 }
 
     CHECK_FOR_EXCEPTION_AT_END();
 }
 
@@ -1251,6 +1399,19 @@ DEFINE_STUB_FUNCTION(void, op_put_by_id_fail)
     CHECK_FOR_EXCEPTION_AT_END();
 }
 
     CHECK_FOR_EXCEPTION_AT_END();
 }
 
+DEFINE_STUB_FUNCTION(void, op_put_by_id_direct_fail)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    
+    CallFrame* callFrame = stackFrame.callFrame;
+    Identifier& ident = stackFrame.args[1].identifier();
+    
+    PutPropertySlot slot;
+    stackFrame.args[0].jsValue().putDirect(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);
 DEFINE_STUB_FUNCTION(JSObject*, op_put_by_id_transition_realloc)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
@@ -1289,7 +1450,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
     // 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.
     // 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());
+    ASSERT(!slot.isCacheableValue() || slot.slotBase().isObject());
 
     // Check that:
     //   * We're dealing with a JSCell,
 
     // Check that:
     //   * We're dealing with a JSCell,
@@ -1300,7 +1461,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_method_check)
     JSCell* specific;
     JSObject* slotBaseObject;
     if (baseValue.isCell()
     JSCell* specific;
     JSObject* slotBaseObject;
     if (baseValue.isCell()
-        && slot.isCacheable()
+        && slot.isCacheableValue()
         && !(structure = asCell(baseValue)->structure())->isUncacheableDictionary()
         && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
         && specific
         && !(structure = asCell(baseValue)->structure())->isUncacheableDictionary()
         && (slotBaseObject = asObject(slot.slotBase()))->getPropertySpecificValue(callFrame, ident, specific)
         && specific
@@ -1389,17 +1550,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
         if (stubInfo->accessType == access_get_by_id_self) {
             ASSERT(!stubInfo->stubRoutine);
             polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);
         if (stubInfo->accessType == access_get_by_id_self) {
             ASSERT(!stubInfo->stubRoutine);
             polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure);
-            stubInfo->initGetByIdSelfList(polymorphicStructureList, 2);
+            stubInfo->initGetByIdSelfList(polymorphicStructureList, 1);
         } else {
             polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
             listIndex = stubInfo->u.getByIdSelfList.listSize;
         } else {
             polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList;
             listIndex = stubInfo->u.getByIdSelfList.listSize;
-            stubInfo->u.getByIdSelfList.listSize++;
         }
         }
+        if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
+            stubInfo->u.getByIdSelfList.listSize++;
+            JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), ident, slot, slot.cachedOffset());
 
 
-        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));
+            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);
     } else
         ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
     return JSValue::encode(result);
@@ -1424,16 +1586,48 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(Str
     case access_get_by_id_proto_list:
         prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
         listIndex = stubInfo->u.getByIdProtoList.listSize;
     case access_get_by_id_proto_list:
         prototypeStructureList = stubInfo->u.getByIdProtoList.structureList;
         listIndex = stubInfo->u.getByIdProtoList.listSize;
-        stubInfo->u.getByIdProtoList.listSize++;
+        if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE)
+            stubInfo->u.getByIdProtoList.listSize++;
         break;
     default:
         ASSERT_NOT_REACHED();
     }
     
         break;
     default:
         ASSERT_NOT_REACHED();
     }
     
-    ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE);
+    ASSERT(listIndex <= POLYMORPHIC_LIST_CACHE_SIZE);
     return prototypeStructureList;
 }
 
     return prototypeStructureList;
 }
 
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_getter_stub)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    CallFrame* callFrame = stackFrame.callFrame;
+    GetterSetter* getterSetter = asGetterSetter(stackFrame.args[0].jsObject());
+    if (!getterSetter->getter())
+        return JSValue::encode(jsUndefined());
+    JSObject* getter = asObject(getterSetter->getter());
+    CallData callData;
+    CallType callType = getter->getCallData(callData);
+    JSValue result = call(callFrame, getter, callType, callData, stackFrame.args[1].jsObject(), ArgList());
+    if (callFrame->hadException())
+        returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[2].returnAddress(), STUB_RETURN_ADDRESS);
+
+    return JSValue::encode(result);
+}
+
+DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_custom_stub)
+{
+    STUB_INIT_STACK_FRAME(stackFrame);
+    CallFrame* callFrame = stackFrame.callFrame;
+    JSObject* slotBase = stackFrame.args[0].jsObject();
+    PropertySlot::GetValueFunc getter = reinterpret_cast<PropertySlot::GetValueFunc>(stackFrame.args[1].asPointer);
+    const Identifier& ident = stackFrame.args[2].identifier();
+    JSValue result = getter(callFrame, slotBase, ident);
+    if (callFrame->hadException())
+        returnToThrowTrampoline(&callFrame->globalData(), stackFrame.args[3].returnAddress(), STUB_RETURN_ADDRESS);
+    
+    return JSValue::encode(result);
+}
+
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
@@ -1474,21 +1668,24 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
 
         int listIndex;
         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
 
         int listIndex;
         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+        if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
+            JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
 
 
-        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));
+            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)) {
         ASSERT(!asCell(baseValue)->structure()->isDictionary());
         int listIndex;
         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
     } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) {
         ASSERT(!asCell(baseValue)->structure()->isDictionary());
         int listIndex;
         PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
+        
+        if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) {
+            StructureChain* protoChain = structure->prototypeChain(callFrame);
+            JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset);
 
 
-        StructureChain* protoChain = structure->prototypeChain(callFrame);
-        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));
+            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));
 
     } else
         ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
 
@@ -1661,6 +1858,14 @@ DEFINE_STUB_FUNCTION(VoidPtrPair, op_call_arityCheck)
     if (argCount > newCodeBlock->m_numParameters) {
         size_t numParameters = newCodeBlock->m_numParameters;
         Register* r = callFrame->registers() + numParameters;
     if (argCount > newCodeBlock->m_numParameters) {
         size_t numParameters = newCodeBlock->m_numParameters;
         Register* r = callFrame->registers() + numParameters;
+        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 - numParameters - argCount;
         for (size_t i = 0; i < numParameters; ++i)
 
         Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argCount;
         for (size_t i = 0; i < numParameters; ++i)
@@ -1688,6 +1893,7 @@ DEFINE_STUB_FUNCTION(VoidPtrPair, op_call_arityCheck)
         callFrame->setCallerFrame(oldCallFrame);
     }
 
         callFrame->setCallerFrame(oldCallFrame);
     }
 
+    ASSERT((void*)callFrame <= stackFrame.registerFile->end());
     RETURN_POINTER_PAIR(callee, callFrame);
 }
 
     RETURN_POINTER_PAIR(callee, callFrame);
 }
 
@@ -1936,31 +2142,38 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
     JSValue baseValue = stackFrame.args[0].jsValue();
     JSValue subscript = stackFrame.args[1].jsValue();
 
     JSValue baseValue = stackFrame.args[0].jsValue();
     JSValue subscript = stackFrame.args[1].jsValue();
 
-    JSValue result;
+    if (LIKELY(baseValue.isCell() && subscript.isString())) {
+        Identifier propertyName(callFrame, asString(subscript)->value(callFrame));
+        PropertySlot slot(asCell(baseValue));
+        // JSString::value may have thrown, but we shouldn't find a property with a null identifier,
+        // so we should miss this case and wind up in the CHECK_FOR_EXCEPTION_AT_END, below.
+        if (asCell(baseValue)->fastGetOwnPropertySlot(callFrame, propertyName, slot)) {
+            JSValue result = slot.getValue(callFrame, propertyName);
+            CHECK_FOR_EXCEPTION();
+            return JSValue::encode(result);
+        }
+    }
 
 
-    if (LIKELY(subscript.isUInt32())) {
+    if (subscript.isUInt32()) {
         uint32_t i = subscript.asUInt32();
         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.
+        if (isJSString(globalData, baseValue) && asString(baseValue)->canGetIndex(i)) {
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
             ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
-            result = asString(baseValue)->getIndex(callFrame, i);
-        } else if (isJSByteArray(globalData, baseValue) && asByteArray(baseValue)->canAccessIndex(i)) {
+            JSValue result = asString(baseValue)->getIndex(callFrame, i);
+            CHECK_FOR_EXCEPTION();
+            return JSValue::encode(result);
+        }
+        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));
             // 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);
+        }
+        JSValue result = baseValue.get(callFrame, i);
+        CHECK_FOR_EXCEPTION();
+        return JSValue::encode(result);
     }
     }
-
+    
+    Identifier property(callFrame, subscript.toString(callFrame));
+    JSValue result = baseValue.get(callFrame, property);
     CHECK_FOR_EXCEPTION_AT_END();
     return JSValue::encode(result);
 }
     CHECK_FOR_EXCEPTION_AT_END();
     return JSValue::encode(result);
 }
@@ -2307,7 +2520,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global)
     PropertySlot slot(globalObject);
     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
         JSValue result = slot.getValue(callFrame, ident);
     PropertySlot slot(globalObject);
     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
         JSValue result = slot.getValue(callFrame, ident);
-        if (slot.isCacheable() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
+        if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
             GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
             if (globalResolveInfo.structure)
                 globalResolveInfo.structure->deref();
             GlobalResolveInfo& globalResolveInfo = callFrame->codeBlock()->globalResolveInfo(globalResolveInfoIndex);
             if (globalResolveInfo.structure)
                 globalResolveInfo.structure->deref();
@@ -2521,10 +2734,9 @@ DEFINE_STUB_FUNCTION(int, op_eq)
 #endif // USE(JSVALUE32_64)
 }
 
 #endif // USE(JSVALUE32_64)
 }
 
-#if USE(JSVALUE32_64)
-
 DEFINE_STUB_FUNCTION(int, op_eq_strings)
 {
 DEFINE_STUB_FUNCTION(int, op_eq_strings)
 {
+#if USE(JSVALUE32_64)
     STUB_INIT_STACK_FRAME(stackFrame);
 
     JSString* string1 = stackFrame.args[0].jsString();
     STUB_INIT_STACK_FRAME(stackFrame);
 
     JSString* string1 = stackFrame.args[0].jsString();
@@ -2533,9 +2745,12 @@ DEFINE_STUB_FUNCTION(int, op_eq_strings)
     ASSERT(string1->isString());
     ASSERT(string2->isString());
     return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
     ASSERT(string1->isString());
     ASSERT(string2->isString());
     return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
-}
-
+#else
+    UNUSED_PARAM(args);
+    ASSERT_NOT_REACHED();
+    return 0;
 #endif
 #endif
+}
 
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
 {
 
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
 {
@@ -2814,7 +3029,9 @@ DEFINE_STUB_FUNCTION(int, has_property)
 
     JSObject* base = stackFrame.args[0].jsObject();
     JSString* property = stackFrame.args[1].jsString();
 
     JSObject* base = stackFrame.args[0].jsObject();
     JSString* property = stackFrame.args[1].jsString();
-    return base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
+    int result = base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
+    CHECK_FOR_EXCEPTION_AT_END();
+    return result;
 }
 
 DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
 }
 
 DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
@@ -2891,7 +3108,9 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_stricteq)
     JSValue src1 = stackFrame.args[0].jsValue();
     JSValue src2 = stackFrame.args[1].jsValue();
 
     JSValue src1 = stackFrame.args[0].jsValue();
     JSValue src2 = stackFrame.args[1].jsValue();
 
-    return JSValue::encode(jsBoolean(JSValue::strictEqual(stackFrame.callFrame, src1, src2)));
+    bool result = JSValue::strictEqual(stackFrame.callFrame, src1, src2);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(jsBoolean(result));
 }
 
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
 }
 
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
@@ -2917,7 +3136,9 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
     JSValue src1 = stackFrame.args[0].jsValue();
     JSValue src2 = stackFrame.args[1].jsValue();
 
     JSValue src1 = stackFrame.args[0].jsValue();
     JSValue src2 = stackFrame.args[1].jsValue();
 
-    return JSValue::encode(jsBoolean(!JSValue::strictEqual(stackFrame.callFrame, src1, src2)));
+    bool result = !JSValue::strictEqual(stackFrame.callFrame, src1, src2);
+    CHECK_FOR_EXCEPTION_AT_END();
+    return JSValue::encode(jsBoolean(result));
 }
 
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
 }
 
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
@@ -3027,10 +3248,11 @@ DEFINE_STUB_FUNCTION(void*, op_switch_char)
 
     if (scrutinee.isString()) {
         UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
 
     if (scrutinee.isString()) {
         UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
-        if (value->size() == 1)
-            result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]).executableAddress();
+        if (value->length() == 1)
+            result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->characters()[0]).executableAddress();
     }
 
     }
 
+    CHECK_FOR_EXCEPTION_AT_END();
     return result;
 }
 
     return result;
 }
 
@@ -3050,6 +3272,7 @@ DEFINE_STUB_FUNCTION(void*, op_switch_string)
         result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
     }
 
         result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
     }
 
+    CHECK_FOR_EXCEPTION_AT_END();
     return result;
 }
 
     return result;
 }
 
@@ -3165,6 +3388,15 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, to_object)
     return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame));
 }
 
     return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame));
 }
 
+NativeExecutable* JITThunks::specializedThunk(JSGlobalData* globalData, ThunkGenerator generator)
+{
+    std::pair<ThunkMap::iterator, bool> entry = m_thunkMap.add(generator, 0);
+    if (!entry.second)
+        return entry.first->second.get();
+    entry.first->second = generator(globalData, m_executablePool.get());
+    return entry.first->second.get();
+}
+
 } // namespace JSC
 
 #endif // ENABLE(JIT)
 } // namespace JSC
 
 #endif // ENABLE(JIT)
index 99c2dd2b7ea9e0bf85f70f679a2e1723b5b4ff3e..0ad9a99979a2be4d37a89af523efa2b9aff4cc39 100644 (file)
 #ifndef JITStubs_h
 #define JITStubs_h
 
 #ifndef JITStubs_h
 #define JITStubs_h
 
-#include <wtf/Platform.h>
-
 #include "MacroAssemblerCodeRef.h"
 #include "Register.h"
 #include "MacroAssemblerCodeRef.h"
 #include "Register.h"
+#include "ThunkGenerators.h"
+#include <wtf/HashMap.h>
 
 #if ENABLE(JIT)
 
 
 #if ENABLE(JIT)
 
@@ -45,16 +45,16 @@ namespace JSC {
     class FunctionExecutable;
     class Identifier;
     class JSGlobalData;
     class FunctionExecutable;
     class Identifier;
     class JSGlobalData;
-    class JSGlobalData;
+    class JSGlobalObject;
     class JSObject;
     class JSPropertyNameIterator;
     class JSValue;
     class JSValueEncodedAsPointer;
     class JSObject;
     class JSPropertyNameIterator;
     class JSValue;
     class JSValueEncodedAsPointer;
+    class NativeExecutable;
     class Profiler;
     class PropertySlot;
     class PutPropertySlot;
     class RegisterFile;
     class Profiler;
     class PropertySlot;
     class PutPropertySlot;
     class RegisterFile;
-    class JSGlobalObject;
     class RegExp;
 
     union JITStubArg {
     class RegExp;
 
     union JITStubArg {
@@ -74,6 +74,14 @@ namespace JSC {
         JSString* jsString() { return static_cast<JSString*>(asPointer); }
         ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); }
     };
         JSString* jsString() { return static_cast<JSString*>(asPointer); }
         ReturnAddressPtr returnAddress() { return ReturnAddressPtr(asPointer); }
     };
+    
+    struct TrampolineStructure {
+        MacroAssemblerCodePtr ctiStringLengthTrampoline;
+        MacroAssemblerCodePtr ctiVirtualCallLink;
+        MacroAssemblerCodePtr ctiVirtualCall;
+        RefPtr<NativeExecutable> ctiNativeCallThunk;
+        MacroAssemblerCodePtr ctiSoftModulo;
+    };
 
 #if CPU(X86_64)
     struct JITStackFrame {
 
 #if CPU(X86_64)
     struct JITStackFrame {
@@ -100,10 +108,10 @@ namespace JSC {
         ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
     };
 #elif CPU(X86)
         ReturnAddressPtr* returnAddressSlot() { return reinterpret_cast<ReturnAddressPtr*>(this) - 1; }
     };
 #elif CPU(X86)
-#if COMPILER(MSVC)
+#if COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
 #pragma pack(push)
 #pragma pack(4)
 #pragma pack(push)
 #pragma pack(4)
-#endif // COMPILER(MSVC)
+#endif // COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
     struct JITStackFrame {
         void* reserved; // Unused
         JITStubArg args[6];
     struct JITStackFrame {
         void* reserved; // Unused
         JITStubArg args[6];
@@ -127,9 +135,9 @@ namespace JSC {
         // 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; }
     };
         // 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)
+#if COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
 #pragma pack(pop)
 #pragma pack(pop)
-#endif // COMPILER(MSVC)
+#endif // COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
 #elif CPU(ARM_THUMB2)
     struct JITStackFrame {
         void* reserved; // Unused
 #elif CPU(ARM_THUMB2)
     struct JITStackFrame {
         void* reserved; // Unused
@@ -181,6 +189,30 @@ namespace JSC {
         JSGlobalData* globalData;
 
         // When JIT code makes a call, it pushes its return address just below the rest of the stack.
         JSGlobalData* globalData;
 
         // When JIT code makes a call, it pushes its return address just below the rest of the stack.
+        ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
+    };
+#elif CPU(MIPS)
+    struct JITStackFrame {
+        void* reserved; // Unused
+        JITStubArg args[6];
+
+        void* preservedGP; // store GP when using PIC code
+        void* preservedS0;
+        void* preservedS1;
+        void* preservedS2;
+        void* preservedReturnAddress;
+
+        ReturnAddressPtr thunkReturnAddress;
+
+        // These arguments passed in a1..a3 (a0 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
         ReturnAddressPtr* returnAddressSlot() { return &thunkReturnAddress; }
     };
 #else
@@ -235,22 +267,24 @@ namespace JSC {
     class JITThunks {
     public:
         JITThunks(JSGlobalData*);
     class JITThunks {
     public:
         JITThunks(JSGlobalData*);
+        ~JITThunks();
 
         static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo);
 
         static void tryCacheGetByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const Identifier& propertyName, const PropertySlot&, StructureStubInfo* stubInfo);
-        static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo);
+        static void tryCachePutByID(CallFrame*, CodeBlock*, ReturnAddressPtr returnAddress, JSValue baseValue, const PutPropertySlot&, StructureStubInfo* stubInfo, bool direct);
 
 
-        MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_ctiStringLengthTrampoline; }
-        MacroAssemblerCodePtr ctiVirtualCallLink() { return m_ctiVirtualCallLink; }
-        MacroAssemblerCodePtr ctiVirtualCall() { return m_ctiVirtualCall; }
-        MacroAssemblerCodePtr ctiNativeCallThunk() { return m_ctiNativeCallThunk; }
+        MacroAssemblerCodePtr ctiStringLengthTrampoline() { return m_trampolineStructure.ctiStringLengthTrampoline; }
+        MacroAssemblerCodePtr ctiVirtualCallLink() { return m_trampolineStructure.ctiVirtualCallLink; }
+        MacroAssemblerCodePtr ctiVirtualCall() { return m_trampolineStructure.ctiVirtualCall; }
+        NativeExecutable* ctiNativeCallThunk() { return m_trampolineStructure.ctiNativeCallThunk.get(); }
+        MacroAssemblerCodePtr ctiSoftModulo() { return m_trampolineStructure.ctiSoftModulo; }
 
 
+        NativeExecutable* specializedThunk(JSGlobalData* globalData, ThunkGenerator generator);
     private:
     private:
+        typedef HashMap<ThunkGenerator, RefPtr<NativeExecutable> > ThunkMap;
+        ThunkMap m_thunkMap;
         RefPtr<ExecutablePool> m_executablePool;
 
         RefPtr<ExecutablePool> m_executablePool;
 
-        MacroAssemblerCodePtr m_ctiStringLengthTrampoline;
-        MacroAssemblerCodePtr m_ctiVirtualCallLink;
-        MacroAssemblerCodePtr m_ctiVirtualCall;
-        MacroAssemblerCodePtr m_ctiNativeCallThunk;
+        TrampolineStructure m_trampolineStructure;
     };
 
 extern "C" {
     };
 
 extern "C" {
@@ -270,6 +304,8 @@ extern "C" {
     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_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_getter_stub(STUB_ARGS_DECLARATION);
+    EncodedJSValue JIT_STUB cti_op_get_by_id_custom_stub(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_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);
@@ -301,6 +337,7 @@ extern "C" {
     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(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_global_dynamic(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_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);
@@ -328,9 +365,7 @@ extern "C" {
     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);
     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);
     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_jless(STUB_ARGS_DECLARATION);
     int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION);
     int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION);
@@ -349,6 +384,9 @@ extern "C" {
     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(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_direct(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_id_direct_fail(STUB_ARGS_DECLARATION);
+    void JIT_STUB cti_op_put_by_id_direct_generic(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_byte_array(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_byte_array(STUB_ARGS_DECLARATION);
diff --git a/jit/JSInterfaceJIT.h b/jit/JSInterfaceJIT.h
new file mode 100644 (file)
index 0000000..f34800a
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2010 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. 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 INC. 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 JSInterfaceJIT_h
+#define JSInterfaceJIT_h
+
+#include "JITCode.h"
+#include "JITStubs.h"
+#include "JSImmediate.h"
+#include "MacroAssembler.h"
+#include "RegisterFile.h"
+#include <wtf/AlwaysInline.h>
+#include <wtf/Vector.h>
+
+namespace JSC {
+    class JSInterfaceJIT : public MacroAssembler {
+    public:
+        // 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 CPU(X86_64)
+        static const RegisterID returnValueRegister = X86Registers::eax;
+        static const RegisterID cachedResultRegister = X86Registers::eax;
+        static const RegisterID firstArgumentRegister = X86Registers::edi;
+        
+        static const RegisterID timeoutCheckRegister = X86Registers::r12;
+        static const RegisterID callFrameRegister = X86Registers::r13;
+        static const RegisterID tagTypeNumberRegister = X86Registers::r14;
+        static const RegisterID tagMaskRegister = X86Registers::r15;
+        
+        static const RegisterID regT0 = X86Registers::eax;
+        static const RegisterID regT1 = X86Registers::edx;
+        static const RegisterID regT2 = X86Registers::ecx;
+        static const RegisterID regT3 = X86Registers::ebx;
+        
+        static const FPRegisterID fpRegT0 = X86Registers::xmm0;
+        static const FPRegisterID fpRegT1 = X86Registers::xmm1;
+        static const FPRegisterID fpRegT2 = X86Registers::xmm2;
+        static const FPRegisterID fpRegT3 = X86Registers::xmm3;
+#elif CPU(X86)
+        static const RegisterID returnValueRegister = X86Registers::eax;
+        static const RegisterID cachedResultRegister = X86Registers::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 = X86Registers::ecx;
+        
+        static const RegisterID timeoutCheckRegister = X86Registers::esi;
+        static const RegisterID callFrameRegister = X86Registers::edi;
+        
+        static const RegisterID regT0 = X86Registers::eax;
+        static const RegisterID regT1 = X86Registers::edx;
+        static const RegisterID regT2 = X86Registers::ecx;
+        static const RegisterID regT3 = X86Registers::ebx;
+        
+        static const FPRegisterID fpRegT0 = X86Registers::xmm0;
+        static const FPRegisterID fpRegT1 = X86Registers::xmm1;
+        static const FPRegisterID fpRegT2 = X86Registers::xmm2;
+        static const FPRegisterID fpRegT3 = X86Registers::xmm3;
+#elif CPU(ARM_THUMB2)
+        static const RegisterID returnValueRegister = ARMRegisters::r0;
+        static const RegisterID cachedResultRegister = ARMRegisters::r0;
+        static const RegisterID firstArgumentRegister = ARMRegisters::r0;
+        
+        static const RegisterID regT0 = ARMRegisters::r0;
+        static const RegisterID regT1 = ARMRegisters::r1;
+        static const RegisterID regT2 = ARMRegisters::r2;
+        static const RegisterID regT3 = ARMRegisters::r4;
+        
+        static const RegisterID callFrameRegister = ARMRegisters::r5;
+        static const RegisterID timeoutCheckRegister = ARMRegisters::r6;
+        
+        static const FPRegisterID fpRegT0 = ARMRegisters::d0;
+        static const FPRegisterID fpRegT1 = ARMRegisters::d1;
+        static const FPRegisterID fpRegT2 = ARMRegisters::d2;
+        static const FPRegisterID fpRegT3 = ARMRegisters::d3;
+#elif CPU(ARM_TRADITIONAL)
+        static const RegisterID returnValueRegister = ARMRegisters::r0;
+        static const RegisterID cachedResultRegister = ARMRegisters::r0;
+        static const RegisterID firstArgumentRegister = ARMRegisters::r0;
+        
+        static const RegisterID timeoutCheckRegister = ARMRegisters::r5;
+        static const RegisterID callFrameRegister = ARMRegisters::r4;
+        
+        static const RegisterID regT0 = ARMRegisters::r0;
+        static const RegisterID regT1 = ARMRegisters::r1;
+        static const RegisterID regT2 = ARMRegisters::r2;
+        // Callee preserved
+        static const RegisterID regT3 = ARMRegisters::r7;
+        
+        static const RegisterID regS0 = ARMRegisters::S0;
+        // Callee preserved
+        static const RegisterID regS1 = ARMRegisters::S1;
+        
+        static const RegisterID regStackPtr = ARMRegisters::sp;
+        static const RegisterID regLink = ARMRegisters::lr;
+        
+        static const FPRegisterID fpRegT0 = ARMRegisters::d0;
+        static const FPRegisterID fpRegT1 = ARMRegisters::d1;
+        static const FPRegisterID fpRegT2 = ARMRegisters::d2;
+        static const FPRegisterID fpRegT3 = ARMRegisters::d3;
+#elif CPU(MIPS)
+        static const RegisterID returnValueRegister = MIPSRegisters::v0;
+        static const RegisterID cachedResultRegister = MIPSRegisters::v0;
+        static const RegisterID firstArgumentRegister = MIPSRegisters::a0;
+        
+        // regT0 must be v0 for returning a 32-bit value.
+        static const RegisterID regT0 = MIPSRegisters::v0;
+        
+        // regT1 must be v1 for returning a pair of 32-bit value.
+        static const RegisterID regT1 = MIPSRegisters::v1;
+        
+        static const RegisterID regT2 = MIPSRegisters::t4;
+        
+        // regT3 must be saved in the callee, so use an S register.
+        static const RegisterID regT3 = MIPSRegisters::s2;
+        
+        static const RegisterID callFrameRegister = MIPSRegisters::s0;
+        static const RegisterID timeoutCheckRegister = MIPSRegisters::s1;
+        
+        static const FPRegisterID fpRegT0 = MIPSRegisters::f4;
+        static const FPRegisterID fpRegT1 = MIPSRegisters::f6;
+        static const FPRegisterID fpRegT2 = MIPSRegisters::f8;
+        static const FPRegisterID fpRegT2 = MIPSRegisters::f10;
+#else
+#error "JIT not supported on this platform."
+#endif
+
+        inline Jump emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload);
+        inline Jump emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst);
+        inline Jump emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch);
+
+#if USE(JSVALUE32_64)
+        inline Jump emitJumpIfNotJSCell(unsigned virtualRegisterIndex);
+        inline Address tagFor(unsigned index, RegisterID base = callFrameRegister);
+#endif
+
+#if USE(JSVALUE32) || USE(JSVALUE64)
+        Jump emitJumpIfImmediateNumber(RegisterID reg);
+        Jump emitJumpIfNotImmediateNumber(RegisterID reg);
+        void emitFastArithImmToInt(RegisterID reg);
+#endif
+
+        inline Address payloadFor(unsigned index, RegisterID base = callFrameRegister);
+        inline Address addressFor(unsigned index, RegisterID base = callFrameRegister);
+    };
+
+    struct ThunkHelpers {
+        static unsigned stringImplDataOffset() { return WebCore::StringImpl::dataOffset(); }
+        static unsigned jsStringLengthOffset() { return OBJECT_OFFSETOF(JSString, m_length); }
+        static unsigned jsStringValueOffset() { return OBJECT_OFFSETOF(JSString, m_value); }
+    };
+
+#if USE(JSVALUE32_64)
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID payload)
+    {
+        loadPtr(payloadFor(virtualRegisterIndex), payload);
+        return emitJumpIfNotJSCell(virtualRegisterIndex);
+    }
+
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotJSCell(unsigned virtualRegisterIndex)
+    {
+        ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
+        return branch32(NotEqual, tagFor(virtualRegisterIndex), Imm32(JSValue::CellTag));
+    }
+    
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst)
+    {
+        ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
+        loadPtr(payloadFor(virtualRegisterIndex), dst);
+        return branch32(NotEqual, tagFor(virtualRegisterIndex), Imm32(JSValue::Int32Tag));
+    }
+    
+    inline JSInterfaceJIT::Address JSInterfaceJIT::tagFor(unsigned virtualRegisterIndex, RegisterID base)
+    {
+        ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
+        return Address(base, (virtualRegisterIndex * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.tag));
+    }
+    
+    inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(unsigned virtualRegisterIndex, RegisterID base)
+    {
+        ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
+        return Address(base, (virtualRegisterIndex * sizeof(Register)) + OBJECT_OFFSETOF(JSValue, u.asBits.payload));
+    }
+
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch)
+    {
+        ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
+        loadPtr(tagFor(virtualRegisterIndex), scratch);
+        Jump isDouble = branch32(Below, scratch, Imm32(JSValue::LowestTag));
+        Jump notInt = branch32(NotEqual, scratch, Imm32(JSValue::Int32Tag));
+        loadPtr(payloadFor(virtualRegisterIndex), scratch);
+        convertInt32ToDouble(scratch, dst);
+        Jump done = jump();
+        isDouble.link(this);
+        loadDouble(addressFor(virtualRegisterIndex), dst);
+        done.link(this);
+        return notInt;
+    }    
+#endif
+
+#if USE(JSVALUE64)
+    ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfImmediateNumber(RegisterID reg)
+    {
+        return branchTestPtr(NonZero, reg, tagTypeNumberRegister);
+    }
+    ALWAYS_INLINE JSInterfaceJIT::Jump JSInterfaceJIT::emitJumpIfNotImmediateNumber(RegisterID reg)
+    {
+        return branchTestPtr(Zero, reg, tagTypeNumberRegister);
+    }
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID dst)
+    {
+        loadPtr(addressFor(virtualRegisterIndex), dst);
+        return branchTestPtr(NonZero, dst, tagMaskRegister);
+    }
+    
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst)
+    {
+        loadPtr(addressFor(virtualRegisterIndex), dst);
+        Jump result = branchPtr(Below, dst, tagTypeNumberRegister);
+        zeroExtend32ToPtr(dst, dst);
+        return result;
+    }
+
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned virtualRegisterIndex, FPRegisterID dst, RegisterID scratch)
+    {
+        loadPtr(addressFor(virtualRegisterIndex), scratch);
+        Jump notNumber = emitJumpIfNotImmediateNumber(scratch);
+        Jump notInt = branchPtr(Below, scratch, tagTypeNumberRegister);
+        convertInt32ToDouble(scratch, dst);
+        Jump done = jump();
+        notInt.link(this);
+        addPtr(tagTypeNumberRegister, scratch);
+        movePtrToDouble(scratch, dst);
+        done.link(this);
+        return notNumber;
+    }
+    
+    ALWAYS_INLINE void JSInterfaceJIT::emitFastArithImmToInt(RegisterID)
+    {
+    }
+    
+#endif
+
+#if USE(JSVALUE32)
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadJSCell(unsigned virtualRegisterIndex, RegisterID dst)
+    {
+        loadPtr(addressFor(virtualRegisterIndex), dst);
+        return branchTest32(NonZero, dst, Imm32(JSImmediate::TagMask));
+    }
+
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadInt32(unsigned virtualRegisterIndex, RegisterID dst)
+    {
+        loadPtr(addressFor(virtualRegisterIndex), dst);
+        Jump result = branchTest32(Zero, dst, Imm32(JSImmediate::TagTypeNumber));
+        rshift32(Imm32(JSImmediate::IntegerPayloadShift), dst);
+        return result;
+    }
+
+    inline JSInterfaceJIT::Jump JSInterfaceJIT::emitLoadDouble(unsigned, FPRegisterID, RegisterID)
+    {
+        ASSERT_NOT_REACHED();
+        return jump();
+    }
+    
+    ALWAYS_INLINE void JSInterfaceJIT::emitFastArithImmToInt(RegisterID reg)
+    {
+        rshift32(Imm32(JSImmediate::IntegerPayloadShift), reg);
+    }
+    
+#endif
+
+#if !USE(JSVALUE32_64)
+    inline JSInterfaceJIT::Address JSInterfaceJIT::payloadFor(unsigned virtualRegisterIndex, RegisterID base)
+    {
+        ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
+        return addressFor(virtualRegisterIndex, base);
+    }
+#endif
+
+    inline JSInterfaceJIT::Address JSInterfaceJIT::addressFor(unsigned virtualRegisterIndex, RegisterID base)
+    {
+        ASSERT(static_cast<int>(virtualRegisterIndex) < FirstConstantRegisterIndex);
+        return Address(base, (virtualRegisterIndex * sizeof(Register)));
+    }
+
+}
+
+#endif // JSInterfaceJIT_h
diff --git a/jit/SpecializedThunkJIT.h b/jit/SpecializedThunkJIT.h
new file mode 100644 (file)
index 0000000..a05be67
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010 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. 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 INC. 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 SpecializedThunkJIT_h
+#define SpecializedThunkJIT_h
+
+#if ENABLE(JIT)
+
+#include "Executable.h"
+#include "JSInterfaceJIT.h"
+#include "LinkBuffer.h"
+
+namespace JSC {
+
+    class SpecializedThunkJIT : public JSInterfaceJIT {
+    public:
+        static const int ThisArgument = -1;
+        SpecializedThunkJIT(int expectedArgCount, JSGlobalData* globalData, ExecutablePool* pool)
+            : m_expectedArgCount(expectedArgCount)
+            , m_globalData(globalData)
+            , m_pool(pool)
+        {
+            // Check that we have the expected number of arguments
+            m_failures.append(branch32(NotEqual, Address(callFrameRegister, RegisterFile::ArgumentCount * (int)sizeof(Register)), Imm32(expectedArgCount + 1)));
+        }
+        
+        void loadDoubleArgument(int argument, FPRegisterID dst, RegisterID scratch)
+        {
+            unsigned src = argumentToVirtualRegister(argument);
+            m_failures.append(emitLoadDouble(src, dst, scratch));
+        }
+        
+        void loadCellArgument(int argument, RegisterID dst)
+        {
+            unsigned src = argumentToVirtualRegister(argument);
+            m_failures.append(emitLoadJSCell(src, dst));
+        }
+        
+        void loadJSStringArgument(int argument, RegisterID dst)
+        {
+            loadCellArgument(argument, dst);
+            m_failures.append(branchPtr(NotEqual, Address(dst, 0), ImmPtr(m_globalData->jsStringVPtr)));
+            m_failures.append(branchTest32(NonZero, Address(dst, OBJECT_OFFSETOF(JSString, m_fiberCount))));
+        }
+        
+        void loadInt32Argument(int argument, RegisterID dst, Jump& failTarget)
+        {
+            unsigned src = argumentToVirtualRegister(argument);
+            failTarget = emitLoadInt32(src, dst);
+        }
+        
+        void loadInt32Argument(int argument, RegisterID dst)
+        {
+            Jump conversionFailed;
+            loadInt32Argument(argument, dst, conversionFailed);
+            m_failures.append(conversionFailed);
+        }
+        
+        void appendFailure(const Jump& failure)
+        {
+            m_failures.append(failure);
+        }
+
+        void returnJSValue(RegisterID src)
+        {
+            if (src != regT0)
+                move(src, regT0);
+            loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
+            ret();
+        }
+        
+        void returnDouble(FPRegisterID src)
+        {
+#if USE(JSVALUE64)
+            moveDoubleToPtr(src, regT0);
+            subPtr(tagTypeNumberRegister, regT0);
+#elif USE(JSVALUE32_64)
+            storeDouble(src, Address(stackPointerRegister, -(int)sizeof(double)));
+            loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.tag) - sizeof(double)), regT1);
+            loadPtr(Address(stackPointerRegister, OBJECT_OFFSETOF(JSValue, u.asBits.payload) - sizeof(double)), regT0);
+#else
+            UNUSED_PARAM(src);
+            ASSERT_NOT_REACHED();
+            m_failures.append(jump());
+#endif
+            loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
+            ret();
+        }
+
+        void returnInt32(RegisterID src)
+        {
+            if (src != regT0)
+                move(src, regT0);
+            tagReturnAsInt32();
+            loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
+            ret();
+        }
+
+        void returnJSCell(RegisterID src)
+        {
+            if (src != regT0)
+                move(src, regT0);
+            tagReturnAsJSCell();
+            loadPtr(Address(callFrameRegister, RegisterFile::CallerFrame * (int)sizeof(Register)), callFrameRegister);
+            ret();
+        }
+        
+        PassRefPtr<NativeExecutable> finalize()
+        {
+            LinkBuffer patchBuffer(this, m_pool.get());
+            patchBuffer.link(m_failures, CodeLocationLabel(m_globalData->jitStubs->ctiNativeCallThunk()->generatedJITCode().addressForCall()));
+            return adoptRef(new NativeExecutable(patchBuffer.finalizeCode()));
+        }
+        
+    private:
+        int argumentToVirtualRegister(unsigned argument)
+        {
+            return -static_cast<int>(RegisterFile::CallFrameHeaderSize + (m_expectedArgCount - argument));
+        }
+
+        void tagReturnAsInt32()
+        {
+#if USE(JSVALUE64)
+            orPtr(tagTypeNumberRegister, regT0);
+#elif USE(JSVALUE32_64)
+            move(Imm32(JSValue::Int32Tag), regT1);
+#else
+            signExtend32ToPtr(regT0, regT0);
+            // If we can't tag the result, give up and jump to the slow case
+            m_failures.append(branchAddPtr(Overflow, regT0, regT0));
+            addPtr(Imm32(JSImmediate::TagTypeNumber), regT0);
+#endif
+        }
+
+        void tagReturnAsJSCell()
+        {
+#if USE(JSVALUE32_64)
+            move(Imm32(JSValue::CellTag), regT1);
+#endif
+        }
+        
+        int m_expectedArgCount;
+        JSGlobalData* m_globalData;
+        RefPtr<ExecutablePool> m_pool;
+        MacroAssembler::JumpList m_failures;
+    };
+
+}
+
+#endif // ENABLE(JIT)
+
+#endif // SpecializedThunkJIT_h
diff --git a/jit/ThunkGenerators.cpp b/jit/ThunkGenerators.cpp
new file mode 100644 (file)
index 0000000..72b2d1a
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2010 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. 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 INC. 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 "ThunkGenerators.h"
+
+#include "CodeBlock.h"
+#include <wtf/text/StringImpl.h>
+#include "SpecializedThunkJIT.h"
+
+#if ENABLE(JIT)
+
+namespace JSC {
+
+static void stringCharLoad(SpecializedThunkJIT& jit)
+{
+    // load string
+    jit.loadJSStringArgument(SpecializedThunkJIT::ThisArgument, SpecializedThunkJIT::regT0);
+    // regT0 now contains this, and is a non-rope JSString*
+
+    // Load string length to regT2, and start the process of loading the data pointer into regT0
+    jit.load32(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::jsStringLengthOffset()), SpecializedThunkJIT::regT2);
+    jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::jsStringValueOffset()), SpecializedThunkJIT::regT0);
+    jit.loadPtr(MacroAssembler::Address(SpecializedThunkJIT::regT0, ThunkHelpers::stringImplDataOffset()), SpecializedThunkJIT::regT0);
+
+    // load index
+    jit.loadInt32Argument(0, SpecializedThunkJIT::regT1); // regT1 contains the index
+
+    // Do an unsigned compare to simultaneously filter negative indices as well as indices that are too large
+    jit.appendFailure(jit.branch32(MacroAssembler::AboveOrEqual, SpecializedThunkJIT::regT1, SpecializedThunkJIT::regT2));
+
+    // Load the character
+    jit.load16(MacroAssembler::BaseIndex(SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1, MacroAssembler::TimesTwo, 0), SpecializedThunkJIT::regT0);
+}
+
+static void charToString(SpecializedThunkJIT& jit, JSGlobalData* globalData, MacroAssembler::RegisterID src, MacroAssembler::RegisterID dst, MacroAssembler::RegisterID scratch)
+{
+    jit.appendFailure(jit.branch32(MacroAssembler::AboveOrEqual, src, MacroAssembler::Imm32(0x100)));
+    jit.move(MacroAssembler::ImmPtr(globalData->smallStrings.singleCharacterStrings()), scratch);
+    jit.loadPtr(MacroAssembler::BaseIndex(scratch, src, MacroAssembler::ScalePtr, 0), dst);
+    jit.appendFailure(jit.branchTestPtr(MacroAssembler::Zero, dst));
+}
+
+PassRefPtr<NativeExecutable> charCodeAtThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    SpecializedThunkJIT jit(1, globalData, pool);
+    stringCharLoad(jit);
+    jit.returnInt32(SpecializedThunkJIT::regT0);
+    return jit.finalize();
+}
+
+PassRefPtr<NativeExecutable> charAtThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    SpecializedThunkJIT jit(1, globalData, pool);
+    stringCharLoad(jit);
+    charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
+    jit.returnJSCell(SpecializedThunkJIT::regT0);
+    return jit.finalize();
+}
+
+PassRefPtr<NativeExecutable> fromCharCodeThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+    SpecializedThunkJIT jit(1, globalData, pool);
+    // load char code
+    jit.loadInt32Argument(0, SpecializedThunkJIT::regT0);
+    charToString(jit, globalData, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT0, SpecializedThunkJIT::regT1);
+    jit.returnJSCell(SpecializedThunkJIT::regT0);
+    return jit.finalize();
+}
+
+PassRefPtr<NativeExecutable> sqrtThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+#if USE(JSVALUE64) || USE(JSVALUE32_64)
+    SpecializedThunkJIT jit(1, globalData, pool);
+    if (!jit.supportsFloatingPointSqrt())
+        return globalData->jitStubs->ctiNativeCallThunk();
+
+    jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+    jit.sqrtDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
+    jit.returnDouble(SpecializedThunkJIT::fpRegT0);
+    return jit.finalize();
+#else
+    UNUSED_PARAM(pool);
+    return globalData->jitStubs.ctiNativeCallThunk();
+#endif
+}
+
+static const double oneConstant = 1.0;
+static const double negativeHalfConstant = -0.5;
+
+PassRefPtr<NativeExecutable> powThunkGenerator(JSGlobalData* globalData, ExecutablePool* pool)
+{
+#if USE(JSVALUE64) || USE(JSVALUE32_64)
+    SpecializedThunkJIT jit(2, globalData, pool);
+    if (!jit.supportsFloatingPoint())
+        return globalData->jitStubs->ctiNativeCallThunk();
+
+    jit.loadDouble(&oneConstant, SpecializedThunkJIT::fpRegT1);
+    jit.loadDoubleArgument(0, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::regT0);
+    MacroAssembler::Jump nonIntExponent;
+    jit.loadInt32Argument(1, SpecializedThunkJIT::regT0, nonIntExponent);
+    jit.appendFailure(jit.branch32(MacroAssembler::LessThan, SpecializedThunkJIT::regT0, MacroAssembler::Imm32(0)));
+    
+    MacroAssembler::Jump exponentIsZero = jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT0);
+    MacroAssembler::Label startLoop(jit.label());
+
+    MacroAssembler::Jump exponentIsEven = jit.branchTest32(MacroAssembler::Zero, SpecializedThunkJIT::regT0, MacroAssembler::Imm32(1));
+    jit.mulDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1);
+    exponentIsEven.link(&jit);
+    jit.mulDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
+    jit.rshift32(MacroAssembler::Imm32(1), SpecializedThunkJIT::regT0);
+    jit.branchTest32(MacroAssembler::NonZero, SpecializedThunkJIT::regT0).linkTo(startLoop, &jit);
+
+    exponentIsZero.link(&jit);
+    jit.returnDouble(SpecializedThunkJIT::fpRegT1);
+
+    if (jit.supportsFloatingPointSqrt()) {
+        nonIntExponent.link(&jit);
+        jit.loadDouble(&negativeHalfConstant, SpecializedThunkJIT::fpRegT3);
+        jit.loadDoubleArgument(1, SpecializedThunkJIT::fpRegT2, SpecializedThunkJIT::regT0);
+        jit.appendFailure(jit.branchDouble(MacroAssembler::DoubleLessThanOrEqual, SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1));
+        jit.appendFailure(jit.branchDouble(MacroAssembler::DoubleNotEqualOrUnordered, SpecializedThunkJIT::fpRegT2, SpecializedThunkJIT::fpRegT3));
+        jit.sqrtDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT0);
+        jit.divDouble(SpecializedThunkJIT::fpRegT0, SpecializedThunkJIT::fpRegT1);
+        jit.returnDouble(SpecializedThunkJIT::fpRegT1);
+    } else
+        jit.appendFailure(nonIntExponent);
+
+    return jit.finalize();
+#else
+    UNUSED_PARAM(pool);
+    return globalData->jitStubs.ctiNativeCallThunk();
+#endif
+}
+
+}
+
+#endif // ENABLE(JIT)
diff --git a/jit/ThunkGenerators.h b/jit/ThunkGenerators.h
new file mode 100644 (file)
index 0000000..c3374f2
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 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. 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 INC. 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 ThunkGenerators_h
+#define ThunkGenerators_h
+
+#if ENABLE(JIT)
+#include <wtf/PassRefPtr.h>
+
+namespace JSC {
+    class ExecutablePool;
+    class JSGlobalData;
+    class NativeExecutable;
+
+    typedef PassRefPtr<NativeExecutable> (*ThunkGenerator)(JSGlobalData*, ExecutablePool*);
+    PassRefPtr<NativeExecutable> charCodeAtThunkGenerator(JSGlobalData*, ExecutablePool*);
+    PassRefPtr<NativeExecutable> charAtThunkGenerator(JSGlobalData*, ExecutablePool*);
+    PassRefPtr<NativeExecutable> fromCharCodeThunkGenerator(JSGlobalData*, ExecutablePool*);
+    PassRefPtr<NativeExecutable> sqrtThunkGenerator(JSGlobalData*, ExecutablePool*);
+    PassRefPtr<NativeExecutable> powThunkGenerator(JSGlobalData*, ExecutablePool*);
+}
+#endif
+
+#endif // ThunkGenerator_h
diff --git a/jsc.cpp b/jsc.cpp
index 252fb961c98cfc125870ddc730bd3fb3fbf5c046..ae47d55994cb061fb696e8a167e812abe4e3084e 100644 (file)
--- a/jsc.cpp
+++ b/jsc.cpp
@@ -79,7 +79,7 @@ static JSValue JSC_HOST_CALL functionRun(ExecState*, JSObject*, JSValue, const A
 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 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&);
+static NO_RETURN_WITH_VALUE 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&);
 
 #if ENABLE(SAMPLING_FLAGS)
 static JSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*, JSObject*, JSValue, const ArgList&);
@@ -177,7 +177,7 @@ JSValue JSC_HOST_CALL functionPrint(ExecState* exec, JSObject*, JSValue, const A
         if (i)
             putchar(' ');
 
         if (i)
             putchar(' ');
 
-        printf("%s", args.at(i).toString(exec).UTF8String().c_str());
+        printf("%s", args.at(i).toString(exec).UTF8String().data());
     }
 
     putchar('\n');
     }
 
     putchar('\n');
@@ -187,7 +187,7 @@ JSValue JSC_HOST_CALL functionPrint(ExecState* exec, JSObject*, JSValue, const A
 
 JSValue JSC_HOST_CALL functionDebug(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
 
 JSValue JSC_HOST_CALL functionDebug(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    fprintf(stderr, "--> %s\n", args.at(0).toString(exec).UTF8String().c_str());
+    fprintf(stderr, "--> %s\n", args.at(0).toString(exec).UTF8String().data());
     return jsUndefined();
 }
 
     return jsUndefined();
 }
 
@@ -346,7 +346,7 @@ int main(int argc, char** argv)
     // We can't use destructors in the following code because it uses Windows
     // Structured Exception Handling
     int res = 0;
     // We can't use destructors in the following code because it uses Windows
     // Structured Exception Handling
     int res = 0;
-    JSGlobalData* globalData = JSGlobalData::create().releaseRef();
+    JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge).releaseRef();
     TRY
         res = jscmain(argc, argv, globalData);
     EXCEPT(res = 3)
     TRY
         res = jscmain(argc, argv, globalData);
     EXCEPT(res = 3)
@@ -445,7 +445,7 @@ static void runInteractive(GlobalObject* globalObject)
         if (completion.complType() == Throw)
             printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).ascii());
         else
         if (completion.complType() == Throw)
             printf("Exception: %s\n", completion.value().toString(globalObject->globalExec()).ascii());
         else
-            printf("%s\n", completion.value().toString(globalObject->globalExec()).UTF8String().c_str());
+            printf("%s\n", completion.value().toString(globalObject->globalExec()).UTF8String().data());
 
         globalObject->globalExec()->clearException();
     }
 
         globalObject->globalExec()->clearException();
     }
@@ -535,9 +535,9 @@ int jscmain(int argc, char** argv, JSGlobalData* globalData)
 
 static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer)
 {
 
 static bool fillBufferWithContentsOfFile(const UString& fileName, Vector<char>& buffer)
 {
-    FILE* f = fopen(fileName.UTF8String().c_str(), "r");
+    FILE* f = fopen(fileName.UTF8String().data(), "r");
     if (!f) {
     if (!f) {
-        fprintf(stderr, "Could not open file: %s\n", fileName.UTF8String().c_str());
+        fprintf(stderr, "Could not open file: %s\n", fileName.UTF8String().data());
         return false;
     }
 
         return false;
     }
 
diff --git a/jsc.pro b/jsc.pro
index 9bcf08bcf9fde142dad0c6e3fdde4eeea49c6f81..420a3f119d15d3902c04a1d49ea371339f8958ed 100644 (file)
--- a/jsc.pro
+++ b/jsc.pro
@@ -8,13 +8,13 @@ CONFIG += building-libs
 win32-*: CONFIG += console
 win32-msvc*: CONFIG += exceptions_off stl_off
 
 win32-*: CONFIG += console
 win32-msvc*: CONFIG += exceptions_off stl_off
 
+isEmpty(OUTPUT_DIR): OUTPUT_DIR= ..
 include($$PWD/../WebKit.pri)
 
 CONFIG += link_pkgconfig
 
 QMAKE_RPATHDIR += $$OUTPUT_DIR/lib
 
 include($$PWD/../WebKit.pri)
 
 CONFIG += link_pkgconfig
 
 QMAKE_RPATHDIR += $$OUTPUT_DIR/lib
 
-isEmpty(OUTPUT_DIR):OUTPUT_DIR=$$PWD/..
 CONFIG(debug, debug|release) {
     OBJECTS_DIR = obj/debug
 } else { # Release
 CONFIG(debug, debug|release) {
     OBJECTS_DIR = obj/debug
 } else { # Release
@@ -22,9 +22,7 @@ CONFIG(debug, debug|release) {
 }
 OBJECTS_DIR_WTR = $$OBJECTS_DIR$${QMAKE_DIR_SEP}
 include($$PWD/JavaScriptCore.pri)
 }
 OBJECTS_DIR_WTR = $$OBJECTS_DIR$${QMAKE_DIR_SEP}
 include($$PWD/JavaScriptCore.pri)
-
-*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2
-*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3
+addJavaScriptCoreLib(.)
 
 symbian {
     TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices
 
 symbian {
     TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices
index 943a7ccda15434e2b7db8a0440f3afb8e38adc7d..a6b0f6369b19546f88940f6507efabd8548462dd 100755 (executable)
@@ -3,6 +3,7 @@
 export SRCROOT=$PWD
 export WebCore=$PWD
 export CREATE_HASH_TABLE="$SRCROOT/create_hash_table"
 export SRCROOT=$PWD
 export WebCore=$PWD
 export CREATE_HASH_TABLE="$SRCROOT/create_hash_table"
+export CREATE_REGEXP_TABLES="$SRCROOT/create_regex_tables"
 
 mkdir -p DerivedSources/JavaScriptCore
 cd DerivedSources/JavaScriptCore
 
 mkdir -p DerivedSources/JavaScriptCore
 cd DerivedSources/JavaScriptCore
index 1d8787e051343b1c63f9c417923c9a64e3c7cec5..b5dff56607cfb49b9295c786c8f52ddcad0d4a8d 100644 (file)
@@ -61,7 +61,7 @@ CASSERT(sizeof(int16_t) == 2, int16_t_is_two_bytes)
 CASSERT(sizeof(uint16_t) == 2, uint16_t_is_two_bytes)
 CASSERT(sizeof(int32_t) == 4, int32_t_is_four_bytes)
 CASSERT(sizeof(uint32_t) == 4, uint32_t_is_four_bytes)
 CASSERT(sizeof(uint16_t) == 2, uint16_t_is_two_bytes)
 CASSERT(sizeof(int32_t) == 4, int32_t_is_four_bytes)
 CASSERT(sizeof(uint32_t) == 4, uint32_t_is_four_bytes)
-CASSERT(sizeof(int64_t) == 8, int64_t_is_four_bytes)
-CASSERT(sizeof(uint64_t) == 8, uint64_t_is_four_bytes)
+CASSERT(sizeof(int64_t) == 8, int64_t_is_eight_bytes)
+CASSERT(sizeof(uint64_t) == 8, uint64_t_is_eight_bytes)
 
 #endif
 
 #endif
index 717a266819397a96ff7a84e45f7570e4834cbd9d..4d6e7d1954eda8f2fff5ecb908e194be6914f493 100644 (file)
@@ -1987,12 +1987,9 @@ static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, co
 static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n)
 {
     if (n->isNumber()) {
 static ExpressionNode* makeNegateNode(JSGlobalData* globalData, ExpressionNode* n)
 {
     if (n->isNumber()) {
-        NumberNode* number = static_cast<NumberNode*>(n);
-
-        if (number->value() > 0.0) {
-            number->setValue(-number->value());
-            return number;
-        }
+        NumberNode* numberNode = static_cast<NumberNode*>(n);
+        numberNode->setValue(-numberNode->value());
+        return numberNode;
     }
 
     return new (globalData) NegateNode(globalData, n);
     }
 
     return new (globalData) NegateNode(globalData, n);
index 682edb6a03ef039a25730acc4d8342162cde2996..bdeb04936c2b1d4af970ea7482b7e55d9c093e22 100644 (file)
@@ -52,8 +52,6 @@ Lexer::Lexer(JSGlobalData* globalData)
     , m_globalData(globalData)
     , m_keywordTable(JSC::mainTable)
 {
     , m_globalData(globalData)
     , m_keywordTable(JSC::mainTable)
 {
-    m_buffer8.reserveInitialCapacity(initialReadBufferCapacity);
-    m_buffer16.reserveInitialCapacity(initialReadBufferCapacity);
 }
 
 Lexer::~Lexer()
 }
 
 Lexer::~Lexer()
@@ -149,6 +147,9 @@ void Lexer::setCode(const SourceCode& source, ParserArena& arena)
     m_error = false;
     m_atLineStart = true;
 
     m_error = false;
     m_atLineStart = true;
 
+    m_buffer8.reserveInitialCapacity(initialReadBufferCapacity);
+    m_buffer16.reserveInitialCapacity((m_codeEnd - m_code) / 2);
+
     // 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()) {
     // 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()) {
@@ -1009,11 +1010,9 @@ void Lexer::clear()
     m_codeWithoutBOMs.clear();
 
     Vector<char> newBuffer8;
     m_codeWithoutBOMs.clear();
 
     Vector<char> newBuffer8;
-    newBuffer8.reserveInitialCapacity(initialReadBufferCapacity);
     m_buffer8.swap(newBuffer8);
 
     Vector<UChar> newBuffer16;
     m_buffer8.swap(newBuffer8);
 
     Vector<UChar> newBuffer16;
-    newBuffer16.reserveInitialCapacity(initialReadBufferCapacity);
     m_buffer16.swap(newBuffer16);
 
     m_isReparsing = false;
     m_buffer16.swap(newBuffer16);
 
     m_isReparsing = false;
index c216ea86327a1f098e66e0746136e859f7c4c4a3..78521657fce8877c10d15cc4a9650d441157298a 100644 (file)
@@ -1385,12 +1385,6 @@ namespace JSC {
 
         using ParserArenaRefCounted::operator new;
 
 
         using ParserArenaRefCounted::operator new;
 
-        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(); }
 
         ScopeNodeData* data() const { return m_data.get(); }
         void destroyData() { m_data.clear(); }
 
index 4c046d0627903d0ff78bbaadd456994f52fb9ad8..039fc46fec9a2f2ffae30ec2ad3f95d84d4fcb5e 100644 (file)
@@ -27,9 +27,6 @@
 #include "Lexer.h"
 #include <wtf/HashSet.h>
 #include <wtf/Vector.h>
 #include "Lexer.h"
 #include <wtf/HashSet.h>
 #include <wtf/Vector.h>
-#include <memory>
-
-using std::auto_ptr;
 
 #ifndef yyparse
 extern int jscyyparse(void*);
 
 #ifndef yyparse
 extern int jscyyparse(void*);
@@ -50,7 +47,7 @@ void Parser::parse(JSGlobalData* globalData, int* errLine, UString* errMsg)
         errMsg = &defaultErrMsg;
 
     *errLine = -1;
         errMsg = &defaultErrMsg;
 
     *errLine = -1;
-    *errMsg = 0;
+    *errMsg = UString();
 
     Lexer& lexer = *globalData->lexer;
     lexer.setCode(*m_source, m_arena);
 
     Lexer& lexer = *globalData->lexer;
     lexer.setCode(*m_source, m_arena);
index 8ca2eb4b79efddf053cdfc4b56733f96f9e12132..50973d02c2d9d182ed15d27ddaa0f204012f8136 100644 (file)
@@ -198,7 +198,7 @@ static void pchars(const UChar* p, int length, bool isSubject, const MatchData&
         length = md.endSubject - p;
     while (length-- > 0) {
         int c;
         length = md.endSubject - p;
     while (length-- > 0) {
         int c;
-        if (isprint(c = *(p++)))
+        if (isASCIIPrintable(c = *(p++)))
             printf("%c", c);
         else if (c < 256)
             printf("\\x%02x", c);
             printf("%c", c);
         else if (c < 256)
             printf("\\x%02x", c);
index ba48c558a5337f08592c42be853aa4b026b77a2a..f2d04fca91b32a565dd1f141f3de1a51a5a659d0 100644 (file)
@@ -44,7 +44,7 @@ namespace JSC {
 
         CallIdentifier(const UString& name, const UString& url, int lineNumber)
             : m_name(name)
 
         CallIdentifier(const UString& name, const UString& url, int lineNumber)
             : m_name(name)
-            , m_url(url)
+            , m_url(!url.isNull() ? url : "")
             , m_lineNumber(lineNumber)
         {
         }
             , m_lineNumber(lineNumber)
         {
         }
@@ -71,7 +71,7 @@ namespace JSC {
 
 #ifndef NDEBUG
         operator const char*() const { return c_str(); }
 
 #ifndef NDEBUG
         operator const char*() const { return c_str(); }
-        const char* c_str() const { return m_name.UTF8String().c_str(); }
+        const char* c_str() const { return m_name.UTF8String().data(); }
 #endif
     };
 
 #endif
     };
 
index de75e71c614e48507af6ce8a0c065e6c55badfc8..126e6f686e54bf4a75ea99df2546211d7ca0b10b 100644 (file)
@@ -42,7 +42,7 @@ Profile::Profile(const UString& title, unsigned uid)
 {
     // FIXME: When multi-threading is supported this will be a vector and calls
     // into the profiler will need to know which thread it is executing on.
 {
     // FIXME: When multi-threading is supported this will be a vector and calls
     // into the profiler will need to know which thread it is executing on.
-    m_head = ProfileNode::create(CallIdentifier("Thread_1", 0, 0), 0, 0);
+    m_head = ProfileNode::create(CallIdentifier("Thread_1", UString(), 0), 0, 0);
 }
 
 Profile::~Profile()
 }
 
 Profile::~Profile()
@@ -127,7 +127,7 @@ void Profile::debugPrintDataSampleStyle() const
 
     std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator);
     for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it)
 
     std::sort(sortedFunctions.begin(), sortedFunctions.end(), functionNameCountPairComparator);
     for (NameCountPairVector::iterator it = sortedFunctions.begin(); it != sortedFunctions.end(); ++it)
-        printf("        %-12d%s\n", (*it).second, UString((*it).first).UTF8String().c_str());
+        printf("        %-12d%s\n", (*it).second, UString((*it).first).UTF8String().data());
 
     printf("\nSort by top of stack, same collapsed (when >= 5):\n");
 }
 
     printf("\nSort by top of stack, same collapsed (when >= 5):\n");
 }
index 17d37d7071d9900a3c391e8b317dc83846e77835..bdfa27b22c967d73417aef214288d5fa85e501a5 100644 (file)
@@ -77,7 +77,7 @@ void ProfileGenerator::willExecute(const CallIdentifier& callIdentifier)
     if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) {
         CString name = callIdentifier.m_name.UTF8String();
         CString url = callIdentifier.m_url.UTF8String();
     if (JAVASCRIPTCORE_PROFILE_WILL_EXECUTE_ENABLED()) {
         CString name = callIdentifier.m_name.UTF8String();
         CString url = callIdentifier.m_url.UTF8String();
-        JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.c_str()), const_cast<char*>(url.c_str()), callIdentifier.m_lineNumber);
+        JAVASCRIPTCORE_PROFILE_WILL_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber);
     }
 
     if (!m_originatingGlobalExec)
     }
 
     if (!m_originatingGlobalExec)
@@ -92,7 +92,7 @@ void ProfileGenerator::didExecute(const CallIdentifier& callIdentifier)
     if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) {
         CString name = callIdentifier.m_name.UTF8String();
         CString url = callIdentifier.m_url.UTF8String();
     if (JAVASCRIPTCORE_PROFILE_DID_EXECUTE_ENABLED()) {
         CString name = callIdentifier.m_name.UTF8String();
         CString url = callIdentifier.m_url.UTF8String();
-        JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.c_str()), const_cast<char*>(url.c_str()), callIdentifier.m_lineNumber);
+        JAVASCRIPTCORE_PROFILE_DID_EXECUTE(m_profileGroup, const_cast<char*>(name.data()), const_cast<char*>(url.data()), callIdentifier.m_lineNumber);
     }
 
     if (!m_originatingGlobalExec)
     }
 
     if (!m_originatingGlobalExec)
@@ -124,7 +124,7 @@ void ProfileGenerator::stopProfiling()
     m_currentNode = m_currentNode->parent();
 
    if (double headSelfTime = m_head->selfTime()) {
     m_currentNode = m_currentNode->parent();
 
    if (double headSelfTime = m_head->selfTime()) {
-        RefPtr<ProfileNode> idleNode = ProfileNode::create(CallIdentifier(NonJSExecution, 0, 0), m_head.get(), m_head.get());
+        RefPtr<ProfileNode> idleNode = ProfileNode::create(CallIdentifier(NonJSExecution, UString(), 0), m_head.get(), m_head.get());
 
         idleNode->setTotalTime(headSelfTime);
         idleNode->setSelfTime(headSelfTime);
 
         idleNode->setTotalTime(headSelfTime);
         idleNode->setSelfTime(headSelfTime);
index fb126b3febd5e84a688a767b66843da6d0adef69..f60c72e48649bf344b1ca2ca62247662053853d1 100644 (file)
@@ -32,6 +32,7 @@
 #include "Profiler.h"
 #include <stdio.h>
 #include <wtf/DateMath.h>
 #include "Profiler.h"
 #include <stdio.h>
 #include <wtf/DateMath.h>
+#include <wtf/text/StringHash.h>
 
 #if OS(WINDOWS)
 #include <windows.h>
 
 #if OS(WINDOWS)
 #include <windows.h>
@@ -293,11 +294,11 @@ void ProfileNode::debugPrintData(int indentLevel) const
         printf("  ");
 
     printf("Function Name %s %d SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% VSelf %.3fms VTotal %.3fms Visible %s Next Sibling %s\n",
         printf("  ");
 
     printf("Function Name %s %d SelfTime %.3fms/%.3f%% TotalTime %.3fms/%.3f%% VSelf %.3fms VTotal %.3fms Visible %s Next Sibling %s\n",
-        functionName().UTF8String().c_str(), 
+        functionName().UTF8String().data(), 
         m_numberOfCalls, m_actualSelfTime, selfPercent(), m_actualTotalTime, totalPercent(),
         m_visibleSelfTime, m_visibleTotalTime, 
         (m_visible ? "True" : "False"),
         m_numberOfCalls, m_actualSelfTime, selfPercent(), m_actualTotalTime, totalPercent(),
         m_visibleSelfTime, m_visibleTotalTime, 
         (m_visible ? "True" : "False"),
-        m_nextSibling ? m_nextSibling->functionName().UTF8String().c_str() : "");
+        m_nextSibling ? m_nextSibling->functionName().UTF8String().data() : "");
 
     ++indentLevel;
 
 
     ++indentLevel;
 
@@ -312,7 +313,7 @@ double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashC
     printf("    ");
 
     // Print function names
     printf("    ");
 
     // Print function names
-    const char* name = functionName().UTF8String().c_str();
+    const char* name = functionName().UTF8String().data();
     double sampleCount = m_actualTotalTime * 1000;
     if (indentLevel) {
         for (int i = 0; i < indentLevel; ++i)
     double sampleCount = m_actualTotalTime * 1000;
     if (indentLevel) {
         for (int i = 0; i < indentLevel; ++i)
@@ -338,7 +339,7 @@ double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashC
         while (indentLevel--)
             printf("  ");
 
         while (indentLevel--)
             printf("  ");
 
-        printf("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().UTF8String().c_str());
+        printf("%.0f %s\n", sampleCount - sumOfChildrensCount, functionName().UTF8String().data());
     }
 
     return m_actualTotalTime;
     }
 
     return m_actualTotalTime;
index c87eaf4482b229d2abbba96e43fe433ee0d1c913..88629c79f6b59d8d85afd75bc18c239c55857be2 100644 (file)
@@ -13,14 +13,20 @@ CONFIG(debug, debug|release) {
     OBJECTS_DIR = obj/release
 }
 
     OBJECTS_DIR = obj/release
 }
 
+isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../..
 include($$PWD/../../../WebKit.pri)
 include($$PWD/../../../WebKit.pri)
+
 include($$PWD/../../JavaScriptCore.pri)
 include($$PWD/../../JavaScriptCore.pri)
+addJavaScriptCoreLib(../..)
 
 INCLUDEPATH += $$PWD/../../API
 
 SOURCES +=  $$PWD/qscriptengine.cpp \
             $$PWD/qscriptengine_p.cpp \
             $$PWD/qscriptvalue.cpp \
 
 INCLUDEPATH += $$PWD/../../API
 
 SOURCES +=  $$PWD/qscriptengine.cpp \
             $$PWD/qscriptengine_p.cpp \
             $$PWD/qscriptvalue.cpp \
+            $$PWD/qscriptstring.cpp \
+            $$PWD/qscriptprogram.cpp \
+            $$PWD/qscriptsyntaxcheckresult.cpp \
 
 HEADERS +=  $$PWD/qtscriptglobal.h \
             $$PWD/qscriptengine.h \
 
 HEADERS +=  $$PWD/qtscriptglobal.h \
             $$PWD/qscriptengine.h \
@@ -28,9 +34,13 @@ HEADERS +=  $$PWD/qtscriptglobal.h \
             $$PWD/qscriptvalue.h \
             $$PWD/qscriptvalue_p.h \
             $$PWD/qscriptconverter_p.h \
             $$PWD/qscriptvalue.h \
             $$PWD/qscriptvalue_p.h \
             $$PWD/qscriptconverter_p.h \
+            $$PWD/qscriptstring.h \
+            $$PWD/qscriptstring_p.h \
+            $$PWD/qscriptprogram.h \
+            $$PWD/qscriptprogram_p.h \
+            $$PWD/qscriptsyntaxcheckresult.h \
 
 
 !static: DEFINES += QT_MAKEDLL
 
 DESTDIR = $$OUTPUT_DIR/lib
 
 
 !static: DEFINES += QT_MAKEDLL
 
 DESTDIR = $$OUTPUT_DIR/lib
-
index c3ca41f051e57a289a6e15ec11f089d5e49d50bd..cd86e2074c7c2930001d7d728ea423d9895476c3 100644 (file)
 #define qscriptconverter_p_h
 
 #include <JavaScriptCore/JavaScript.h>
 #define qscriptconverter_p_h
 
 #include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qnumeric.h>
 #include <QtCore/qstring.h>
 #include <QtCore/qstring.h>
+#include <QtCore/qvarlengtharray.h>
+
+extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str);
 
 /*
   \internal
 
 /*
   \internal
 */
 class QScriptConverter {
 public:
 */
 class QScriptConverter {
 public:
+    static quint32 toArrayIndex(const JSStringRef jsstring)
+    {
+        // FIXME this function should be exported by JSC C API.
+        QString qstring = toString(jsstring);
+
+        bool ok;
+        quint32 idx = qstring.toUInt(&ok);
+        if (!ok || toString(idx) != qstring)
+            idx = 0xffffffff;
+
+        return idx;
+    }
+
     static QString toString(const JSStringRef str)
     {
         return QString(reinterpret_cast<const QChar*>(JSStringGetCharactersPtr(str)), JSStringGetLength(str));
     static QString toString(const JSStringRef str)
     {
         return QString(reinterpret_cast<const QChar*>(JSStringGetCharactersPtr(str)), JSStringGetLength(str));
@@ -45,6 +62,71 @@ public:
     {
         return JSStringCreateWithUTF8CString(str);
     }
     {
         return JSStringCreateWithUTF8CString(str);
     }
+    static QString toString(double value)
+    {
+        // FIXME this should be easier. The ideal fix is to create
+        // a new function in JSC C API which could cover the functionality.
+
+        if (qIsNaN(value))
+            return QString::fromLatin1("NaN");
+        if (qIsInf(value))
+            return QString::fromLatin1(value < 0 ? "-Infinity" : "Infinity");
+        if (!value)
+            return QString::fromLatin1("0");
+
+        QVarLengthArray<char, 25> buf;
+        int decpt;
+        int sign;
+        char* result = 0;
+        char* endresult;
+        (void)qdtoa(value, 0, 0, &decpt, &sign, &endresult, &result);
+
+        if (!result)
+            return QString();
+
+        int resultLen = endresult - result;
+        if (decpt <= 0 && decpt > -6) {
+            buf.resize(-decpt + 2 + sign);
+            qMemSet(buf.data(), '0', -decpt + 2 + sign);
+            if (sign) // fix the sign.
+                buf[0] = '-';
+            buf[sign + 1] = '.';
+            buf.append(result, resultLen);
+        } else {
+            if (sign)
+                buf.append('-');
+            int length = buf.size() - sign + resultLen;
+            if (decpt <= 21 && decpt > 0) {
+                if (length <= decpt) {
+                    const char* zeros = "0000000000000000000000000";
+                    buf.append(result, resultLen);
+                    buf.append(zeros, decpt - length);
+                } else {
+                    buf.append(result, decpt);
+                    buf.append('.');
+                    buf.append(result + decpt, resultLen - decpt);
+                }
+            } else if (result[0] >= '0' && result[0] <= '9') {
+                if (length > 1) {
+                    buf.append(result, 1);
+                    buf.append('.');
+                    buf.append(result + 1, resultLen - 1);
+                } else
+                    buf.append(result, resultLen);
+                buf.append('e');
+                buf.append(decpt >= 0 ? '+' : '-');
+                int e = qAbs(decpt - 1);
+                if (e >= 100)
+                    buf.append('0' + e / 100);
+                if (e >= 10)
+                    buf.append('0' + (e % 100) / 10);
+                buf.append('0' + e % 10);
+            }
+        }
+        free(result);
+        buf.append(0);
+        return QString::fromLatin1(buf.constData());
+    }
 };
 
 #endif // qscriptconverter_p_h
 };
 
 #endif // qscriptconverter_p_h
index f12f4103287ca522206667a192b92382a2149f4a..d49c578162c1b7702d16eaccb297179ac52ef5e7 100644 (file)
@@ -22,6 +22,8 @@
 #include "qscriptengine.h"
 
 #include "qscriptengine_p.h"
 #include "qscriptengine.h"
 
 #include "qscriptengine_p.h"
+#include "qscriptprogram_p.h"
+#include "qscriptsyntaxcheckresult_p.h"
 #include "qscriptvalue_p.h"
 
 /*!
 #include "qscriptvalue_p.h"
 
 /*!
@@ -41,6 +43,23 @@ QScriptEngine::~QScriptEngine()
 {
 }
 
 {
 }
 
+/*!
+  Checks the syntax of the given \a program. Returns a
+  QScriptSyntaxCheckResult object that contains the result of the check.
+*/
+QScriptSyntaxCheckResult QScriptEngine::checkSyntax(const QString &program)
+{
+    // FIXME This is not optimal.
+    // The JSC C API needs a context to perform a syntax check, it means that a QScriptEnginePrivate
+    // had to be created. This function is static so we have to create QScriptEnginePrivate for each
+    // call. We can't remove the "static" for compatibility reason, at least up to Qt5.
+    // QScriptSyntaxCheckResultPrivate takes ownership of newly created engine. The engine will be
+    // kept as long as it is needed for lazy evaluation of properties of
+    // the QScriptSyntaxCheckResultPrivate.
+    QScriptEnginePrivate* engine = new QScriptEnginePrivate(/* q_ptr */ 0);
+    return QScriptSyntaxCheckResultPrivate::get(engine->checkSyntax(program));
+}
+
 /*!
     Evaluates \a program, using \a lineNumber as the base line number,
     and returns the result of the evaluation.
 /*!
     Evaluates \a program, using \a lineNumber as the base line number,
     and returns the result of the evaluation.
@@ -71,6 +90,11 @@ QScriptValue QScriptEngine::evaluate(const QString& program, const QString& file
     return QScriptValuePrivate::get(d_ptr->evaluate(program, fileName, lineNumber));
 }
 
     return QScriptValuePrivate::get(d_ptr->evaluate(program, fileName, lineNumber));
 }
 
+QScriptValue QScriptEngine::evaluate(const QScriptProgram& program)
+{
+    return QScriptValuePrivate::get(d_ptr->evaluate(QScriptProgramPrivate::get(program)));
+}
+
 /*!
     Runs the garbage collector.
 
 /*!
     Runs the garbage collector.
 
@@ -81,8 +105,82 @@ QScriptValue QScriptEngine::evaluate(const QString& program, const QString& file
     when the QScriptEngine decides that it's wise to do so (i.e. when a certain number of new objects
     have been created). However, you can call this function to explicitly request that garbage
     collection should be performed as soon as possible.
     when the QScriptEngine decides that it's wise to do so (i.e. when a certain number of new objects
     have been created). However, you can call this function to explicitly request that garbage
     collection should be performed as soon as possible.
+
+    \sa reportAdditionalMemoryCost()
 */
 void QScriptEngine::collectGarbage()
 {
     d_ptr->collectGarbage();
 }
 */
 void QScriptEngine::collectGarbage()
 {
     d_ptr->collectGarbage();
 }
+
+/*!
+  Reports an additional memory cost of the given \a size, measured in
+  bytes, to the garbage collector.
+
+  This function can be called to indicate that a JavaScript object has
+  memory associated with it that isn't managed by Qt Script itself.
+  Reporting the additional cost makes it more likely that the garbage
+  collector will be triggered.
+
+  Note that if the additional memory is shared with objects outside
+  the scripting environment, the cost should not be reported, since
+  collecting the JavaScript object would not cause the memory to be
+  freed anyway.
+
+  Negative \a size values are ignored, i.e. this function can't be
+  used to report that the additional memory has been deallocated.
+
+  \sa collectGarbage()
+*/
+void QScriptEngine::reportAdditionalMemoryCost(int cost)
+{
+    d_ptr->reportAdditionalMemoryCost(cost);
+}
+
+/*!
+  Returns a handle that represents the given string, \a str.
+
+  QScriptString can be used to quickly look up properties, and
+  compare property names, of script objects.
+
+  \sa QScriptValue::property()
+*/
+QScriptString QScriptEngine::toStringHandle(const QString& str)
+{
+    return QScriptStringPrivate::get(d_ptr->toStringHandle(str));
+}
+
+/*!
+  Returns a QScriptValue of the primitive type Null.
+
+  \sa undefinedValue()
+*/
+QScriptValue QScriptEngine::nullValue()
+{
+    return QScriptValue(this, QScriptValue::NullValue);
+}
+
+/*!
+  Returns a QScriptValue of the primitive type Undefined.
+
+  \sa nullValue()
+*/
+QScriptValue QScriptEngine::undefinedValue()
+{
+    return QScriptValue(this, QScriptValue::UndefinedValue);
+}
+
+/*!
+  Returns this engine's Global Object.
+
+  By default, the Global Object contains the built-in objects that are
+  part of \l{ECMA-262}, such as Math, Date and String. Additionally,
+  you can set properties of the Global Object to make your own
+  extensions available to all script code. Non-local variables in
+  script code will be created as properties of the Global Object, as
+  well as local variables in global code.
+*/
+QScriptValue QScriptEngine::globalObject() const
+{
+    return QScriptValuePrivate::get(d_ptr->globalObject());
+}
index cf61d357094cdee4aefa8cea6bfa836865175ea4..e10888dc1b41476b9afeee1bbd9c4a85c42e64c7 100644 (file)
@@ -20,6 +20,9 @@
 #ifndef qscriptengine_h
 #define qscriptengine_h
 
 #ifndef qscriptengine_h
 #define qscriptengine_h
 
+#include "qscriptprogram.h"
+#include "qscriptstring.h"
+#include "qscriptsyntaxcheckresult.h"
 #include <QtCore/qobject.h>
 #include <QtCore/qshareddata.h>
 #include <QtCore/qstring.h>
 #include <QtCore/qobject.h>
 #include <QtCore/qshareddata.h>
 #include <QtCore/qstring.h>
@@ -35,9 +38,18 @@ public:
     QScriptEngine();
     ~QScriptEngine();
 
     QScriptEngine();
     ~QScriptEngine();
 
+    static QScriptSyntaxCheckResult checkSyntax(const QString& program);
     QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
     QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
+    QScriptValue evaluate(const QScriptProgram& program);
+
     void collectGarbage();
     void collectGarbage();
+    void reportAdditionalMemoryCost(int cost);
+
+    QScriptString toStringHandle(const QString& str);
 
 
+    QScriptValue nullValue();
+    QScriptValue undefinedValue();
+    QScriptValue globalObject() const;
 private:
     friend class QScriptEnginePrivate;
 
 private:
     friend class QScriptEnginePrivate;
 
index de8a3559e35d00360ccddbd517a3f30706b0240c..38185abd91e9eb02613a2552b55a58dc4dbd92d1 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "qscriptengine_p.h"
 
 
 #include "qscriptengine_p.h"
 
+#include "qscriptprogram_p.h"
 #include "qscriptvalue_p.h"
 
 /*!
 #include "qscriptvalue_p.h"
 
 /*!
@@ -38,6 +39,19 @@ QScriptEnginePrivate::~QScriptEnginePrivate()
     JSGlobalContextRelease(m_context);
 }
 
     JSGlobalContextRelease(m_context);
 }
 
+QScriptSyntaxCheckResultPrivate* QScriptEnginePrivate::checkSyntax(const QString& program)
+{
+    JSValueRef exception;
+    JSStringRef source = QScriptConverter::toString(program);
+    bool syntaxIsCorrect = JSCheckScriptSyntax(m_context, source, /* url */ 0, /* starting line */ 1, &exception);
+    JSStringRelease(source);
+    if (syntaxIsCorrect) {
+        return new QScriptSyntaxCheckResultPrivate(this);
+    }
+    JSValueProtect(m_context, exception);
+    return new QScriptSyntaxCheckResultPrivate(this, const_cast<JSObjectRef>(exception));
+}
+
 /*!
     Evaluates program and returns the result of the evaluation.
     \internal
 /*!
     Evaluates program and returns the result of the evaluation.
     \internal
@@ -46,9 +60,25 @@ QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QString& program, cons
 {
     JSStringRef script = QScriptConverter::toString(program);
     JSStringRef file = QScriptConverter::toString(fileName);
 {
     JSStringRef script = QScriptConverter::toString(program);
     JSStringRef file = QScriptConverter::toString(fileName);
-    JSValueRef exception;
-    JSValueRef result = JSEvaluateScript(m_context, script, /* Global Object */ 0, file, lineNumber, &exception);
-    if (!result)
-        return new QScriptValuePrivate(this, exception); // returns an exception
-    return new QScriptValuePrivate(this, result);
+    QScriptValuePrivate* result = new QScriptValuePrivate(this, evaluate(script, file, lineNumber));
+    JSStringRelease(script);
+    JSStringRelease(file);
+    return result;
+}
+
+/*!
+    Evaluates program and returns the result of the evaluation.
+    \internal
+*/
+QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QScriptProgramPrivate* program)
+{
+    if (program->isNull())
+        return new QScriptValuePrivate;
+    return new QScriptValuePrivate(this, evaluate(program->program(), program->file(), program->line()));
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::globalObject() const
+{
+    JSObjectRef globalObject = JSContextGetGlobalObject(context());
+    return new QScriptValuePrivate(this, globalObject, globalObject);
 }
 }
index 8e27c427154cb1654b5208ecca0241df02def83e..c6c64dd9fed483b723313c618c094a3ce1c5e9ca 100644 (file)
 
 #include "qscriptconverter_p.h"
 #include "qscriptengine.h"
 
 #include "qscriptconverter_p.h"
 #include "qscriptengine.h"
+#include "qscriptstring_p.h"
+#include "qscriptsyntaxcheckresult_p.h"
 #include "qscriptvalue.h"
 #include <JavaScriptCore/JavaScript.h>
 #include "qscriptvalue.h"
 #include <JavaScriptCore/JavaScript.h>
+#include <JSBasePrivate.h>
 #include <QtCore/qshareddata.h>
 #include <QtCore/qstring.h>
 
 class QScriptEngine;
 #include <QtCore/qshareddata.h>
 #include <QtCore/qstring.h>
 
 class QScriptEngine;
+class QScriptSyntaxCheckResultPrivate;
 
 class QScriptEnginePrivate : public QSharedData {
 public:
 
 class QScriptEnginePrivate : public QSharedData {
 public:
-    static QScriptEnginePtr get(const QScriptEngine* q) { Q_ASSERT(q); return q->d_ptr; }
+    static QScriptEnginePrivate* get(const QScriptEngine* q) { Q_ASSERT(q); return q->d_ptr.data(); }
     static QScriptEngine* get(const QScriptEnginePrivate* d) { Q_ASSERT(d); return d->q_ptr; }
 
     QScriptEnginePrivate(const QScriptEngine*);
     ~QScriptEnginePrivate();
 
     static QScriptEngine* get(const QScriptEnginePrivate* d) { Q_ASSERT(d); return d->q_ptr; }
 
     QScriptEnginePrivate(const QScriptEngine*);
     ~QScriptEnginePrivate();
 
+    QScriptSyntaxCheckResultPrivate* checkSyntax(const QString& program);
     QScriptValuePrivate* evaluate(const QString& program, const QString& fileName, int lineNumber);
     QScriptValuePrivate* evaluate(const QString& program, const QString& fileName, int lineNumber);
+    QScriptValuePrivate* evaluate(const QScriptProgramPrivate* program);
+    inline JSValueRef evaluate(JSStringRef program, JSStringRef fileName, int lineNumber);
+
     inline void collectGarbage();
     inline void collectGarbage();
+    inline void reportAdditionalMemoryCost(int cost);
 
     inline JSValueRef makeJSValue(double number) const;
     inline JSValueRef makeJSValue(int number) const;
 
     inline JSValueRef makeJSValue(double number) const;
     inline JSValueRef makeJSValue(int number) const;
@@ -47,17 +56,42 @@ public:
     inline JSValueRef makeJSValue(bool number) const;
     inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const;
 
     inline JSValueRef makeJSValue(bool number) const;
     inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const;
 
+    QScriptValuePrivate* globalObject() const;
+
+    inline QScriptStringPrivate* toStringHandle(const QString& str) const;
+
     inline JSGlobalContextRef context() const;
 private:
     QScriptEngine* q_ptr;
     JSGlobalContextRef m_context;
 };
 
     inline JSGlobalContextRef context() const;
 private:
     QScriptEngine* q_ptr;
     JSGlobalContextRef m_context;
 };
 
+
+/*!
+  Evaluates given JavaScript program and returns result of the evaluation.
+  \attention this function doesn't take ownership of the parameters.
+  \internal
+*/
+JSValueRef QScriptEnginePrivate::evaluate(JSStringRef program, JSStringRef fileName, int lineNumber)
+{
+    JSValueRef exception;
+    JSValueRef result = JSEvaluateScript(m_context, program, /* Global Object */ 0, fileName, lineNumber, &exception);
+    if (!result)
+        return exception; // returns an exception
+    return result;
+}
+
 void QScriptEnginePrivate::collectGarbage()
 {
     JSGarbageCollect(m_context);
 }
 
 void QScriptEnginePrivate::collectGarbage()
 {
     JSGarbageCollect(m_context);
 }
 
+void QScriptEnginePrivate::reportAdditionalMemoryCost(int cost)
+{
+    if (cost > 0)
+        JSReportExtraMemoryCost(m_context, cost);
+}
+
 JSValueRef QScriptEnginePrivate::makeJSValue(double number) const
 {
     return JSValueMakeNumber(m_context, number);
 JSValueRef QScriptEnginePrivate::makeJSValue(double number) const
 {
     return JSValueMakeNumber(m_context, number);
@@ -75,7 +109,10 @@ JSValueRef QScriptEnginePrivate::makeJSValue(uint number) const
 
 JSValueRef QScriptEnginePrivate::makeJSValue(const QString& string) const
 {
 
 JSValueRef QScriptEnginePrivate::makeJSValue(const QString& string) const
 {
-    return JSValueMakeString(m_context, QScriptConverter::toString(string));
+    JSStringRef tmp = QScriptConverter::toString(string);
+    JSValueRef result = JSValueMakeString(m_context, tmp);
+    JSStringRelease(tmp);
+    return result;
 }
 
 JSValueRef QScriptEnginePrivate::makeJSValue(bool value) const
 }
 
 JSValueRef QScriptEnginePrivate::makeJSValue(bool value) const
@@ -90,6 +127,11 @@ JSValueRef QScriptEnginePrivate::makeJSValue(QScriptValue::SpecialValue value) c
     return JSValueMakeUndefined(m_context);
 }
 
     return JSValueMakeUndefined(m_context);
 }
 
+QScriptStringPrivate* QScriptEnginePrivate::toStringHandle(const QString& str) const
+{
+    return new QScriptStringPrivate(str);
+}
+
 JSGlobalContextRef QScriptEnginePrivate::context() const
 {
     return m_context;
 JSGlobalContextRef QScriptEnginePrivate::context() const
 {
     return m_context;
diff --git a/qt/api/qscriptprogram.cpp b/qt/api/qscriptprogram.cpp
new file mode 100644 (file)
index 0000000..d7d4948
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 "qscriptprogram.h"
+
+#include "qscriptprogram_p.h"
+
+/*!
+  \internal
+
+  \class QScriptProgram
+
+  \brief The QScriptProgram class encapsulates a Qt Script program.
+
+  \ingroup script
+
+  QScriptProgram retains the compiled representation of the script if
+  possible. Thus, QScriptProgram can be used to evaluate the same
+  script multiple times more efficiently.
+
+  \code
+  QScriptEngine engine;
+  QScriptProgram program("1 + 2");
+  QScriptValue result = engine.evaluate(program);
+  \endcode
+*/
+
+/*!
+  Constructs a null QScriptProgram.
+*/
+QScriptProgram::QScriptProgram()
+    : d_ptr(new QScriptProgramPrivate)
+{}
+
+/*!
+  Constructs a new QScriptProgram with the given \a sourceCode, \a
+  fileName and \a firstLineNumber.
+*/
+QScriptProgram::QScriptProgram(const QString& sourceCode,
+               const QString fileName,
+               int firstLineNumber)
+    : d_ptr(new QScriptProgramPrivate(sourceCode, fileName, firstLineNumber))
+{}
+
+/*!
+  Destroys this QScriptProgram.
+*/
+QScriptProgram::~QScriptProgram()
+{}
+
+/*!
+  Constructs a new QScriptProgram that is a copy of \a other.
+*/
+QScriptProgram::QScriptProgram(const QScriptProgram& other)
+{
+    d_ptr = other.d_ptr;
+}
+
+/*!
+  Assigns the \a other value to this QScriptProgram.
+*/
+QScriptProgram& QScriptProgram::operator=(const QScriptProgram& other)
+{
+    d_ptr = other.d_ptr;
+    return *this;
+}
+
+/*!
+  Returns true if this QScriptProgram is null; otherwise
+  returns false.
+*/
+bool QScriptProgram::isNull() const
+{
+    return d_ptr->isNull();
+}
+
+/*!
+  Returns the source code of this program.
+*/
+QString QScriptProgram::sourceCode() const
+{
+    return d_ptr->sourceCode();
+}
+
+/*!
+  Returns the filename associated with this program.
+*/
+QString QScriptProgram::fileName() const
+{
+    return d_ptr->fileName();
+}
+
+/*!
+  Returns the line number associated with this program.
+*/
+int QScriptProgram::firstLineNumber() const
+{
+    return d_ptr->firstLineNumber();
+}
+
+/*!
+  Returns true if this QScriptProgram is equal to \a other;
+  otherwise returns false.
+*/
+bool QScriptProgram::operator==(const QScriptProgram& other) const
+{
+    return d_ptr == other.d_ptr || *d_ptr == *other.d_ptr;
+}
+
+/*!
+  Returns true if this QScriptProgram is not equal to \a other;
+  otherwise returns false.
+*/
+bool QScriptProgram::operator!=(const QScriptProgram& other) const
+{
+    return d_ptr != other.d_ptr && *d_ptr != *other.d_ptr;
+}
+
diff --git a/qt/api/qscriptprogram.h b/qt/api/qscriptprogram.h
new file mode 100644 (file)
index 0000000..93c8a3c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 qscriptprogram_h
+#define qscriptprogram_h
+
+#include "qtscriptglobal.h"
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+class QScriptProgramPrivate;
+class Q_JAVASCRIPT_EXPORT QScriptProgram {
+public:
+    QScriptProgram();
+    QScriptProgram(const QString& sourceCode,
+                   const QString fileName = QString(),
+                   int firstLineNumber = 1);
+    QScriptProgram(const QScriptProgram& other);
+    ~QScriptProgram();
+
+    QScriptProgram& operator=(const QScriptProgram& other);
+
+    bool isNull() const;
+
+    QString sourceCode() const;
+    QString fileName() const;
+    int firstLineNumber() const;
+
+    bool operator==(const QScriptProgram& other) const;
+    bool operator!=(const QScriptProgram& other) const;
+
+private:
+    QExplicitlySharedDataPointer<QScriptProgramPrivate> d_ptr;
+    Q_DECLARE_PRIVATE(QScriptProgram)
+};
+
+#endif // qscriptprogram_h
diff --git a/qt/api/qscriptprogram_p.h b/qt/api/qscriptprogram_p.h
new file mode 100644 (file)
index 0000000..6e80e85
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 qscriptprogram_p_h
+#define qscriptprogram_p_h
+
+#include "qscriptconverter_p.h"
+#include "qscriptprogram.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+/*
+   FIXME The QScriptProgramPrivate potentially could be much faster. In current implementation we
+   gain CPU time only by avoiding QString -> JSStringRef conversion. In the ideal world we should
+   have a function inside the JSC C API that could provide us "parse once, execute multiple times"
+   functionality.
+*/
+
+class QScriptProgramPrivate : public QSharedData {
+public:
+    inline static QScriptProgramPrivate* get(const QScriptProgram& program);
+    inline QScriptProgramPrivate();
+    inline QScriptProgramPrivate(const QString& sourceCode,
+                   const QString fileName,
+                   int firstLineNumber);
+
+    inline ~QScriptProgramPrivate();
+
+    inline bool isNull() const;
+
+    inline QString sourceCode() const;
+    inline QString fileName() const;
+    inline int firstLineNumber() const;
+
+    inline bool operator==(const QScriptProgramPrivate& other) const;
+    inline bool operator!=(const QScriptProgramPrivate& other) const;
+
+    inline JSStringRef program() const;
+    inline JSStringRef file() const;
+    inline int line() const;
+private:
+    JSStringRef m_program;
+    JSStringRef m_fileName;
+    int m_line;
+};
+
+QScriptProgramPrivate* QScriptProgramPrivate::get(const QScriptProgram& program)
+{
+    return const_cast<QScriptProgramPrivate*>(program.d_ptr.constData());
+}
+
+QScriptProgramPrivate::QScriptProgramPrivate()
+    : m_program(0)
+    , m_fileName(0)
+    , m_line(-1)
+{}
+
+QScriptProgramPrivate::QScriptProgramPrivate(const QString& sourceCode,
+               const QString fileName,
+               int firstLineNumber)
+                   : m_program(QScriptConverter::toString(sourceCode))
+                   , m_fileName(QScriptConverter::toString(fileName))
+                   , m_line(firstLineNumber)
+{}
+
+QScriptProgramPrivate::~QScriptProgramPrivate()
+{
+    if (!isNull()) {
+        JSStringRelease(m_program);
+        JSStringRelease(m_fileName);
+    }
+}
+
+bool QScriptProgramPrivate::isNull() const
+{
+    return !m_program;
+}
+
+QString QScriptProgramPrivate::sourceCode() const
+{
+    return QScriptConverter::toString(m_program);
+}
+
+QString QScriptProgramPrivate::fileName() const
+{
+    return QScriptConverter::toString(m_fileName);
+}
+
+int QScriptProgramPrivate::firstLineNumber() const
+{
+    return m_line;
+}
+
+bool QScriptProgramPrivate::operator==(const QScriptProgramPrivate& other) const
+{
+    return m_line == other.m_line
+            && JSStringIsEqual(m_fileName, other.m_fileName)
+            && JSStringIsEqual(m_program, other.m_program);
+}
+
+bool QScriptProgramPrivate::operator!=(const QScriptProgramPrivate& other) const
+{
+    return m_line != other.m_line
+            || !JSStringIsEqual(m_fileName, other.m_fileName)
+            || !JSStringIsEqual(m_program, other.m_program);
+}
+
+JSStringRef QScriptProgramPrivate::program() const { return m_program; }
+JSStringRef QScriptProgramPrivate::file() const {return m_fileName; }
+int QScriptProgramPrivate::line() const { return m_line; }
+
+#endif // qscriptprogram_p_h
diff --git a/qt/api/qscriptstring.cpp b/qt/api/qscriptstring.cpp
new file mode 100644 (file)
index 0000000..83c03c5
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 "qscriptstring.h"
+
+#include "qscriptstring_p.h"
+#include <QtCore/qhash.h>
+
+/*!
+  Constructs an invalid QScriptString.
+*/
+QScriptString::QScriptString()
+    : d_ptr(new QScriptStringPrivate())
+{
+}
+/*!
+  Constructs an QScriptString from internal representation
+  \internal
+*/
+QScriptString::QScriptString(QScriptStringPrivate* d)
+    : d_ptr(d)
+{
+}
+
+/*!
+  Constructs a new QScriptString that is a copy of \a other.
+*/
+QScriptString::QScriptString(const QScriptString& other)
+{
+    d_ptr = other.d_ptr;
+}
+
+/*!
+  Destroys this QScriptString.
+*/
+QScriptString::~QScriptString()
+{
+}
+
+/*!
+  Assigns the \a other value to this QScriptString.
+*/
+QScriptString& QScriptString::operator=(const QScriptString& other)
+{
+    d_ptr = other.d_ptr;
+    return *this;
+}
+
+/*!
+  Returns true if this QScriptString is valid; otherwise
+  returns false.
+*/
+bool QScriptString::isValid() const
+{
+    return d_ptr->isValid();
+}
+
+/*!
+  Returns true if this QScriptString is equal to \a other;
+  otherwise returns false.
+*/
+bool QScriptString::operator==(const QScriptString& other) const
+{
+    return d_ptr == other.d_ptr || *d_ptr == *(other.d_ptr);
+}
+
+/*!
+  Returns true if this QScriptString is not equal to \a other;
+  otherwise returns false.
+*/
+bool QScriptString::operator!=(const QScriptString& other) const
+{
+    return d_ptr != other.d_ptr || *d_ptr != *(other.d_ptr);
+}
+
+/*!
+  Attempts to convert this QScriptString to a QtScript array index,
+  and returns the result.
+
+  If a conversion error occurs, *\a{ok} is set to false; otherwise
+  *\a{ok} is set to true.
+*/
+quint32 QScriptString::toArrayIndex(bool* ok) const
+{
+    return d_ptr->toArrayIndex(ok);
+}
+
+/*!
+  Returns the string that this QScriptString represents, or a
+  null string if this QScriptString is not valid.
+
+  \sa isValid()
+*/
+QString QScriptString::toString() const
+{
+    return d_ptr->toString();
+}
+
+/*!
+  Returns the string that this QScriptString represents, or a
+  null string if this QScriptString is not valid.
+
+  \sa toString()
+*/
+QScriptString::operator QString() const
+{
+    return d_ptr->toString();
+}
+
+uint qHash(const QScriptString& key)
+{
+    return qHash(QScriptStringPrivate::get(key)->id());
+}
diff --git a/qt/api/qscriptstring.h b/qt/api/qscriptstring.h
new file mode 100644 (file)
index 0000000..16593bc
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 qscriptstring_h
+#define qscriptstring_h
+
+#include "qtscriptglobal.h"
+#include <QtCore/qshareddata.h>
+#include <QtCore/qstring.h>
+
+class QScriptStringPrivate;
+typedef QExplicitlySharedDataPointer<QScriptStringPrivate> QScriptStringPtr;
+
+class Q_JAVASCRIPT_EXPORT QScriptString {
+public:
+    QScriptString();
+    QScriptString(const QScriptString& other);
+    ~QScriptString();
+
+    QScriptString& operator=(const QScriptString& other);
+
+    bool isValid() const;
+
+    bool operator==(const QScriptString& other) const;
+    bool operator!=(const QScriptString& other) const;
+
+    quint32 toArrayIndex(bool* ok = 0) const;
+
+    QString toString() const;
+    operator QString() const;
+
+private:
+    QScriptString(QScriptStringPrivate* d);
+
+    QScriptStringPtr d_ptr;
+
+    friend class QScriptStringPrivate;
+};
+
+uint qHash(const QScriptString& key);
+
+#endif // qscriptstring_h
diff --git a/qt/api/qscriptstring_p.h b/qt/api/qscriptstring_p.h
new file mode 100644 (file)
index 0000000..d4fc88e
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 qscriptstring_p_h
+#define qscriptstring_p_h
+
+#include "qscriptconverter_p.h"
+#include "qscriptstring.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qshareddata.h>
+
+class QScriptStringPrivate : public QSharedData {
+public:
+    inline QScriptStringPrivate();
+    inline QScriptStringPrivate(const QString& qtstring);
+    inline ~QScriptStringPrivate();
+
+    static inline QScriptString get(QScriptStringPrivate* d);
+    static inline QScriptStringPtr get(const QScriptString& p);
+
+    inline bool isValid() const;
+
+    inline bool operator==(const QScriptStringPrivate& other) const;
+    inline bool operator!=(const QScriptStringPrivate& other) const;
+
+    inline quint32 toArrayIndex(bool* ok = 0) const;
+
+    inline QString toString() const;
+
+    inline quint64 id() const;
+
+private:
+    JSStringRef m_string;
+};
+
+
+QScriptStringPrivate::QScriptStringPrivate()
+    : m_string(0)
+{}
+
+QScriptStringPrivate::QScriptStringPrivate(const QString& qtstring)
+    : m_string(QScriptConverter::toString(qtstring))
+{}
+
+QScriptStringPrivate::~QScriptStringPrivate()
+{
+    if (isValid())
+        JSStringRelease(m_string);
+}
+
+QScriptString QScriptStringPrivate::get(QScriptStringPrivate* d)
+{
+    Q_ASSERT(d);
+    return QScriptString(d);
+}
+
+QScriptStringPtr QScriptStringPrivate::get(const QScriptString& p)
+{
+    return p.d_ptr;
+}
+
+bool QScriptStringPrivate::isValid() const
+{
+    return m_string;
+}
+
+bool QScriptStringPrivate::operator==(const QScriptStringPrivate& other) const
+{
+    return isValid() && other.isValid() && JSStringIsEqual(m_string, other.m_string);
+}
+
+bool QScriptStringPrivate::operator!=(const QScriptStringPrivate& other) const
+{
+    return isValid() && other.isValid() && !JSStringIsEqual(m_string, other.m_string);
+}
+
+quint32 QScriptStringPrivate::toArrayIndex(bool* ok) const
+{
+    quint32 idx = QScriptConverter::toArrayIndex(m_string);
+    if (ok)
+        *ok = (idx != 0xffffffff);
+    return idx;
+}
+
+QString QScriptStringPrivate::toString() const
+{
+    return QScriptConverter::toString(m_string);
+}
+
+quint64 QScriptStringPrivate::id() const
+{
+    return reinterpret_cast<quint32>(m_string);
+}
+
+#endif // qscriptstring_p_h
diff --git a/qt/api/qscriptsyntaxcheckresult.cpp b/qt/api/qscriptsyntaxcheckresult.cpp
new file mode 100644 (file)
index 0000000..5cf02ef
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 "qscriptsyntaxcheckresult.h"
+#include "qscriptsyntaxcheckresult_p.h"
+
+/*!
+  \class QScriptSyntaxCheckResult
+
+  \brief The QScriptSyntaxCheckResult class provides the result of a script syntax check.
+
+  \ingroup script
+  \mainclass
+
+  QScriptSyntaxCheckResult is returned by QScriptEngine::checkSyntax() to
+  provide information about the syntactical (in)correctness of a script.
+*/
+
+/*!
+    \enum QScriptSyntaxCheckResult::State
+
+    This enum specifies the state of a syntax check.
+
+    \value Error The program contains a syntax error.
+    \value Intermediate The program is incomplete.
+    \value Valid The program is a syntactically correct Qt Script program.
+*/
+
+/*!
+  Constructs a new QScriptSyntaxCheckResult from the \a other result.
+*/
+QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult& other)
+    : d_ptr(other.d_ptr)
+{}
+
+/*!
+  Constructs a new QScriptSyntaxCheckResult from an internal representation.
+  \internal
+*/
+QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate* d)
+    : d_ptr(d)
+{}
+
+/*!
+  Destroys this QScriptSyntaxCheckResult.
+*/
+QScriptSyntaxCheckResult::~QScriptSyntaxCheckResult()
+{}
+
+/*!
+  Assigns the \a other result to this QScriptSyntaxCheckResult, and returns a
+  reference to this QScriptSyntaxCheckResult.
+*/
+QScriptSyntaxCheckResult& QScriptSyntaxCheckResult::operator=(const QScriptSyntaxCheckResult& other)
+{
+    d_ptr = other.d_ptr;
+    return *this;
+}
+
+/*!
+  Returns the state of this QScriptSyntaxCheckResult.
+*/
+QScriptSyntaxCheckResult::State QScriptSyntaxCheckResult::state() const
+{
+    return d_ptr->state();
+}
+
+/*!
+  Returns the error line number of this QScriptSyntaxCheckResult, or -1 if
+  there is no error.
+
+  \sa state(), errorMessage()
+*/
+int QScriptSyntaxCheckResult::errorLineNumber() const
+{
+    return d_ptr->errorLineNumber();
+}
+
+/*!
+  Returns the error column number of this QScriptSyntaxCheckResult, or -1 if
+  there is no error.
+
+  \sa state(), errorLineNumber()
+*/
+int QScriptSyntaxCheckResult::errorColumnNumber() const
+{
+    return d_ptr->errorColumnNumber();
+}
+
+/*!
+  Returns the error message of this QScriptSyntaxCheckResult, or an empty
+  string if there is no error.
+
+  \sa state(), errorLineNumber()
+*/
+QString QScriptSyntaxCheckResult::errorMessage() const
+{
+    return d_ptr->errorMessage();
+}
+
+QScriptSyntaxCheckResultPrivate::~QScriptSyntaxCheckResultPrivate()
+{
+    if (m_exception)
+        JSValueUnprotect(m_engine->context(), m_exception);
+}
+
+QString QScriptSyntaxCheckResultPrivate::errorMessage() const
+{
+    if (!m_exception)
+        return QString();
+
+    JSStringRef tmp = JSValueToStringCopy(m_engine->context(), m_exception, /* exception */ 0);
+    QString message = QScriptConverter::toString(tmp);
+    JSStringRelease(tmp);
+    return message;
+}
+
+int QScriptSyntaxCheckResultPrivate::errorLineNumber() const
+{
+    if (!m_exception)
+        return -1;
+    // m_exception is an instance of the Exception so it has "line" attribute.
+    JSStringRef lineAttrName = QScriptConverter::toString("line");
+    JSValueRef line = JSObjectGetProperty(m_engine->context(),
+                                          m_exception,
+                                          lineAttrName,
+                                          /* exceptions */0);
+    JSStringRelease(lineAttrName);
+    return JSValueToNumber(m_engine->context(), line, /* exceptions */0);
+}
diff --git a/qt/api/qscriptsyntaxcheckresult.h b/qt/api/qscriptsyntaxcheckresult.h
new file mode 100644 (file)
index 0000000..aa57744
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 qscriptsyntaxcheckresult_h
+#define qscriptsyntaxcheckresult_h
+
+#include "qtscriptglobal.h"
+#include <QtCore/qshareddata.h>
+
+class QScriptSyntaxCheckResultPrivate;
+class Q_JAVASCRIPT_EXPORT QScriptSyntaxCheckResult {
+public:
+    enum State {
+        Error,
+        Intermediate,
+        Valid
+    };
+
+    QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult& other);
+    ~QScriptSyntaxCheckResult();
+    QScriptSyntaxCheckResult& operator=(const QScriptSyntaxCheckResult& other);
+
+    State state() const;
+    int errorLineNumber() const;
+    int errorColumnNumber() const;
+    QString errorMessage() const;
+
+private:
+    QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate* d);
+    QExplicitlySharedDataPointer<QScriptSyntaxCheckResultPrivate> d_ptr;
+
+    friend class QScriptSyntaxCheckResultPrivate;
+};
+#endif // qscriptsyntaxcheckresult_h
diff --git a/qt/api/qscriptsyntaxcheckresult_p.h b/qt/api/qscriptsyntaxcheckresult_p.h
new file mode 100644 (file)
index 0000000..6e1a131
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 qscriptsyntaxcheckresult_p_h
+#define qscriptsyntaxcheckresult_p_h
+
+#include "qscriptconverter_p.h"
+#include "qscriptengine_p.h"
+#include "qscriptsyntaxcheckresult.h"
+#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qshareddata.h>
+
+class QScriptSyntaxCheckResultPrivate : public QSharedData {
+public:
+    static inline QScriptSyntaxCheckResult get(QScriptSyntaxCheckResultPrivate* p);
+    inline QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine);
+    inline QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine, JSObjectRef value);
+    ~QScriptSyntaxCheckResultPrivate();
+
+    inline QScriptSyntaxCheckResult::State state() const;
+    int errorLineNumber() const;
+    inline int errorColumnNumber() const;
+    QString errorMessage() const;
+private:
+    JSObjectRef m_exception;
+    QScriptEnginePtr m_engine;
+};
+
+QScriptSyntaxCheckResult QScriptSyntaxCheckResultPrivate::get(QScriptSyntaxCheckResultPrivate* p)
+{
+    return QScriptSyntaxCheckResult(p);
+}
+
+QScriptSyntaxCheckResultPrivate::QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine)
+    : m_exception(0)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+{}
+
+QScriptSyntaxCheckResultPrivate::QScriptSyntaxCheckResultPrivate(const QScriptEnginePrivate* engine, JSObjectRef value)
+    : m_exception(value)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+{}
+
+QScriptSyntaxCheckResult::State QScriptSyntaxCheckResultPrivate::state() const
+{
+    // FIXME This function doesn't return QScriptSyntaxCheckResult::Intermediate
+    return m_exception ? QScriptSyntaxCheckResult::Error : QScriptSyntaxCheckResult::Valid;
+}
+
+int QScriptSyntaxCheckResultPrivate::errorColumnNumber() const
+{
+    // FIXME JSC C API doesn't expose the error column number.
+    return m_exception ? 1 : -1;
+}
+
+
+#endif // qscriptsyntaxcheckresult_p_h
index 127fe041010f672044b1813c6b819d8f76e36929..f692817439274ee5cc1a220e2c84b7ff8d85d5e0 100644 (file)
@@ -115,8 +115,11 @@ QScriptValue::QScriptValue(QScriptValuePrivate* d)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, bool value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, bool value)
-    : d_ptr(new QScriptValuePrivate(engine, value))
 {
 {
+    if (engine)
+        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+    else
+        d_ptr = new QScriptValuePrivate(value);
 }
 
 /*!
 }
 
 /*!
@@ -126,8 +129,11 @@ QScriptValue::QScriptValue(QScriptEngine* engine, bool value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, int value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, int value)
-    : d_ptr(new QScriptValuePrivate(engine, value))
 {
 {
+    if (engine)
+        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+    else
+        d_ptr = new QScriptValuePrivate(value);
 }
 
 /*!
 }
 
 /*!
@@ -137,8 +143,11 @@ QScriptValue::QScriptValue(QScriptEngine* engine, int value)
   registers it with the script \a engine.
  */
 QScriptValue::QScriptValue(QScriptEngine* engine, uint value)
   registers it with the script \a engine.
  */
 QScriptValue::QScriptValue(QScriptEngine* engine, uint value)
-    : d_ptr(new QScriptValuePrivate(engine, value))
 {
 {
+    if (engine)
+        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+    else
+        d_ptr = new QScriptValuePrivate(value);
 }
 
 /*!
 }
 
 /*!
@@ -148,8 +157,11 @@ QScriptValue::QScriptValue(QScriptEngine* engine, uint value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value)
-    : d_ptr(new QScriptValuePrivate(engine, value))
 {
 {
+    if (engine)
+        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+    else
+        d_ptr = new QScriptValuePrivate(value);
 }
 
 /*!
 }
 
 /*!
@@ -159,8 +171,11 @@ QScriptValue::QScriptValue(QScriptEngine* engine, qsreal value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value)
-    : d_ptr(new QScriptValuePrivate(engine, value))
 {
 {
+    if (engine)
+        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+    else
+        d_ptr = new QScriptValuePrivate(value);
 }
 
 /*!
 }
 
 /*!
@@ -170,8 +185,11 @@ QScriptValue::QScriptValue(QScriptEngine* engine, const QString& value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, const char* value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, const char* value)
-    : d_ptr(new QScriptValuePrivate(engine, QString::fromUtf8(value)))
 {
 {
+    if (engine)
+        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), QString::fromUtf8(value));
+    else
+        d_ptr = new QScriptValuePrivate(QString::fromUtf8(value));
 }
 
 /*!
 }
 
 /*!
@@ -181,8 +199,11 @@ QScriptValue::QScriptValue(QScriptEngine* engine, const char* value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, SpecialValue value)
   registers it with the script \a engine.
 */
 QScriptValue::QScriptValue(QScriptEngine* engine, SpecialValue value)
-    : d_ptr(new QScriptValuePrivate(engine, value))
 {
 {
+    if (engine)
+        d_ptr = new QScriptValuePrivate(QScriptEnginePrivate::get(engine), value);
+    else
+        d_ptr = new QScriptValuePrivate(value);
 }
 
 /*!
 }
 
 /*!
index 6a5b3884f34bf96f359f4d0bb91cbbeeef0b3d49..03e8621a3ef3fa90f1c468d10b9940baedeb5221 100644 (file)
@@ -24,6 +24,9 @@
 #include "qscriptengine_p.h"
 #include "qscriptvalue.h"
 #include <JavaScriptCore/JavaScript.h>
 #include "qscriptengine_p.h"
 #include "qscriptvalue.h"
 #include <JavaScriptCore/JavaScript.h>
+#include <JavaScriptCore/JSRetainPtr.h>
+#include <QtCore/qmath.h>
+#include <QtCore/qnumeric.h>
 #include <QtCore/qshareddata.h>
 #include <QtCore/qvarlengtharray.h>
 
 #include <QtCore/qshareddata.h>
 #include <QtCore/qvarlengtharray.h>
 
@@ -36,10 +39,10 @@ class QScriptValue;
 
   Implementation of QScriptValue.
   The implementation is based on a state machine. The states names are included in
 
   Implementation of QScriptValue.
   The implementation is based on a state machine. The states names are included in
-  QScriptValuePrivate::States. Each method should check for the current state and then perform a
+  QScriptValuePrivate::State. Each method should check for the current state and then perform a
   correct action.
 
   correct action.
 
-  States:
+  State:
     Invalid -> QSVP is invalid, no assumptions should be made about class members (apart from m_value).
     CString -> QSVP is created from QString or const char* and no JSC engine has been associated yet.
         Current value is kept in m_string,
     Invalid -> QSVP is invalid, no assumptions should be made about class members (apart from m_value).
     CString -> QSVP is created from QString or const char* and no JSC engine has been associated yet.
         Current value is kept in m_string,
@@ -51,7 +54,7 @@ class QScriptValue;
         is kept in m_number (cast of QScriptValue::SpecialValue)
     JSValue -> QSVP is associated with engine, but there is no information about real type, the state
         have really short live cycle. Normally it is created as a function call result.
         is kept in m_number (cast of QScriptValue::SpecialValue)
     JSValue -> QSVP is associated with engine, but there is no information about real type, the state
         have really short live cycle. Normally it is created as a function call result.
-    JSNative -> QSVP is associated with engine, and it is sure that it isn't a JavaScript object.
+    JSPrimitive -> QSVP is associated with engine, and it is sure that it isn't a JavaScript object.
     JSObject -> QSVP is associated with engine, and it is sure that it is a JavaScript object.
 
   Each state keep all necessary information to invoke all methods, if not it should be changed to
     JSObject -> QSVP is associated with engine, and it is sure that it is a JavaScript object.
 
   Each state keep all necessary information to invoke all methods, if not it should be changed to
@@ -74,12 +77,12 @@ public:
     inline QScriptValuePrivate(qsreal number);
     inline QScriptValuePrivate(QScriptValue::SpecialValue value);
 
     inline QScriptValuePrivate(qsreal number);
     inline QScriptValuePrivate(QScriptValue::SpecialValue value);
 
-    inline QScriptValuePrivate(const QScriptEngine* engine, bool value);
-    inline QScriptValuePrivate(const QScriptEngine* engine, int value);
-    inline QScriptValuePrivate(const QScriptEngine* engine, uint value);
-    inline QScriptValuePrivate(const QScriptEngine* engine, qsreal value);
-    inline QScriptValuePrivate(const QScriptEngine* engine, const QString& value);
-    inline QScriptValuePrivate(const QScriptEngine* engine, QScriptValue::SpecialValue value);
+    inline QScriptValuePrivate(const QScriptEnginePrivate* engine, bool value);
+    inline QScriptValuePrivate(const QScriptEnginePrivate* engine, int value);
+    inline QScriptValuePrivate(const QScriptEnginePrivate* engine, uint value);
+    inline QScriptValuePrivate(const QScriptEnginePrivate* engine, qsreal value);
+    inline QScriptValuePrivate(const QScriptEnginePrivate* engine, const QString& value);
+    inline QScriptValuePrivate(const QScriptEnginePrivate* engine, QScriptValue::SpecialValue value);
 
     inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value);
     inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value, JSObjectRef object);
 
     inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value);
     inline QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value, JSObjectRef object);
@@ -115,14 +118,14 @@ public:
 
 private:
     // Please, update class documentation when you change the enum.
 
 private:
     // Please, update class documentation when you change the enum.
-    enum States {
+    enum State {
         Invalid = 0,
         CString = 0x1000,
         CNumber,
         CBool,
         CSpecial,
         JSValue = 0x2000, // JS values are equal or higher then this value.
         Invalid = 0,
         CString = 0x1000,
         CNumber,
         CBool,
         CSpecial,
         JSValue = 0x2000, // JS values are equal or higher then this value.
-        JSNative,
+        JSPrimitive,
         JSObject
     } m_state;
     QScriptEnginePtr m_engine;
         JSObject
     } m_state;
     QScriptEnginePtr m_engine;
@@ -134,6 +137,7 @@ private:
     inline void setValue(JSValueRef);
 
     inline bool inherits(const char*);
     inline void setValue(JSValueRef);
 
     inline bool inherits(const char*);
+    inline State refinedJSValue();
 
     inline bool isJSBased() const;
     inline bool isNumberBased() const;
 
     inline bool isJSBased() const;
     inline bool isNumberBased() const;
@@ -206,94 +210,58 @@ QScriptValuePrivate::QScriptValuePrivate(QScriptValue::SpecialValue value)
 {
 }
 
 {
 }
 
-QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, bool value)
-    : m_state(JSNative)
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, bool value)
+    : m_state(JSPrimitive)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+    , m_value(engine->makeJSValue(value))
 {
 {
-    if (!engine) {
-        // slower path reinitialization
-        m_state = CBool;
-        m_number = value;
-        m_value = 0;
-    } else {
-        m_engine = QScriptEnginePrivate::get(engine);
-        m_value = m_engine->makeJSValue(value);
-        JSValueProtect(context(), m_value);
-    }
+    Q_ASSERT(engine);
+    JSValueProtect(context(), m_value);
 }
 
 }
 
-QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, int value)
-    : m_state(JSNative)
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, int value)
+    : m_state(JSPrimitive)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+    , m_value(m_engine->makeJSValue(value))
 {
 {
-    if (!engine) {
-        // slower path reinitialization
-        m_state = CNumber;
-        m_number = value;
-        m_value = 0;
-    } else {
-        m_engine = QScriptEnginePrivate::get(engine);
-        m_value = m_engine->makeJSValue(value);
-        JSValueProtect(context(), m_value);
-    }
+    Q_ASSERT(engine);
+    JSValueProtect(context(), m_value);
 }
 
 }
 
-QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, uint value)
-    : m_state(JSNative)
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, uint value)
+    : m_state(JSPrimitive)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+    , m_value(m_engine->makeJSValue(value))
 {
 {
-    if (!engine) {
-        // slower path reinitialization
-        m_state = CNumber;
-        m_number = value;
-        m_value = 0;
-    } else {
-        m_engine = QScriptEnginePrivate::get(engine);
-        m_value = m_engine->makeJSValue(value);
-        JSValueProtect(context(), m_value);
-    }
+    Q_ASSERT(engine);
+    JSValueProtect(context(), m_value);
 }
 
 }
 
-QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, qsreal value)
-    : m_state(JSNative)
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, qsreal value)
+    : m_state(JSPrimitive)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+    , m_value(m_engine->makeJSValue(value))
 {
 {
-    if (!engine) {
-        // slower path reinitialization
-        m_state = CNumber;
-        m_number = value;
-        m_value = 0;
-    } else {
-        m_engine = QScriptEnginePrivate::get(engine);
-        m_value = m_engine->makeJSValue(value);
-        JSValueProtect(context(), m_value);
-    }
+    Q_ASSERT(engine);
+    JSValueProtect(context(), m_value);
 }
 
 }
 
-QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, const QString& value)
-    : m_state(JSNative)
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, const QString& value)
+    : m_state(JSPrimitive)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+    , m_value(m_engine->makeJSValue(value))
 {
 {
-    if (!engine) {
-        // slower path reinitialization
-        m_state = CString;
-        m_string = value;
-        m_value = 0;
-    } else {
-        m_engine = QScriptEnginePrivate::get(engine);
-        m_value = m_engine->makeJSValue(value);
-        JSValueProtect(context(), m_value);
-    }
+    Q_ASSERT(engine);
+    JSValueProtect(context(), m_value);
 }
 
 }
 
-QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, QScriptValue::SpecialValue value)
-    : m_state(JSNative)
+QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, QScriptValue::SpecialValue value)
+    : m_state(JSPrimitive)
+    , m_engine(const_cast<QScriptEnginePrivate*>(engine))
+    , m_value(m_engine->makeJSValue(value))
 {
 {
-    if (!engine) {
-        // slower path reinitialization
-        m_state = CSpecial;
-        m_number = value;
-        m_value = 0;
-    } else {
-        m_engine = QScriptEnginePrivate::get(engine);
-        m_value = m_engine->makeJSValue(value);
-        JSValueProtect(context(), m_value);
-    }
+    Q_ASSERT(engine);
+    JSValueProtect(context(), m_value);
 }
 
 QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value)
 }
 
 QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSValueRef value)
@@ -302,6 +270,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSV
     , m_value(value)
 {
     Q_ASSERT(engine);
     , m_value(value)
 {
     Q_ASSERT(engine);
+    Q_ASSERT(value);
     JSValueProtect(context(), m_value);
 }
 
     JSValueProtect(context(), m_value);
 }
 
@@ -312,6 +281,8 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEnginePrivate* engine, JSV
     , m_object(object)
 {
     Q_ASSERT(engine);
     , m_object(object)
 {
     Q_ASSERT(engine);
+    Q_ASSERT(value);
+    Q_ASSERT(object);
     JSValueProtect(context(), m_value);
 }
 
     JSValueProtect(context(), m_value);
 }
 
@@ -323,10 +294,10 @@ bool QScriptValuePrivate::isBool()
     case CBool:
         return true;
     case JSValue:
     case CBool:
         return true;
     case JSValue:
-        if (isObject())
+        if (refinedJSValue() != JSPrimitive)
             return false;
         // Fall-through.
             return false;
         // Fall-through.
-    case JSNative:
+    case JSPrimitive:
         return JSValueIsBoolean(context(), value());
     default:
         return false;
         return JSValueIsBoolean(context(), value());
     default:
         return false;
@@ -337,12 +308,12 @@ bool QScriptValuePrivate::isNumber()
 {
     switch (m_state) {
     case CNumber:
 {
     switch (m_state) {
     case CNumber:
-        return m_number;
+        return true;
     case JSValue:
     case JSValue:
-        if (isObject())
+        if (refinedJSValue() != JSPrimitive)
             return false;
         // Fall-through.
             return false;
         // Fall-through.
-    case JSNative:
+    case JSPrimitive:
         return JSValueIsNumber(context(), value());
     default:
         return false;
         return JSValueIsNumber(context(), value());
     default:
         return false;
@@ -355,10 +326,10 @@ bool QScriptValuePrivate::isNull()
     case CSpecial:
         return m_number == static_cast<int>(QScriptValue::NullValue);
     case JSValue:
     case CSpecial:
         return m_number == static_cast<int>(QScriptValue::NullValue);
     case JSValue:
-        if (isObject())
+        if (refinedJSValue() != JSPrimitive)
             return false;
         // Fall-through.
             return false;
         // Fall-through.
-    case JSNative:
+    case JSPrimitive:
         return JSValueIsNull(context(), value());
     default:
         return false;
         return JSValueIsNull(context(), value());
     default:
         return false;
@@ -371,10 +342,10 @@ bool QScriptValuePrivate::isString()
     case CString:
         return true;
     case JSValue:
     case CString:
         return true;
     case JSValue:
-        if (isObject())
+        if (refinedJSValue() != JSPrimitive)
             return false;
         // Fall-through.
             return false;
         // Fall-through.
-    case JSNative:
+    case JSPrimitive:
         return JSValueIsString(context(), value());
     default:
         return false;
         return JSValueIsString(context(), value());
     default:
         return false;
@@ -387,10 +358,10 @@ bool QScriptValuePrivate::isUndefined()
     case CSpecial:
         return m_number == static_cast<int>(QScriptValue::UndefinedValue);
     case JSValue:
     case CSpecial:
         return m_number == static_cast<int>(QScriptValue::UndefinedValue);
     case JSValue:
-        if (isObject())
+        if (refinedJSValue() != JSPrimitive)
             return false;
         // Fall-through.
             return false;
         // Fall-through.
-    case JSNative:
+    case JSPrimitive:
         return JSValueIsUndefined(context(), value());
     default:
         return false;
         return JSValueIsUndefined(context(), value());
     default:
         return false;
@@ -401,7 +372,7 @@ bool QScriptValuePrivate::isError()
 {
     switch (m_state) {
     case JSValue:
 {
     switch (m_state) {
     case JSValue:
-        if (!isObject())
+        if (refinedJSValue() != JSObject)
             return false;
         // Fall-through.
     case JSObject:
             return false;
         // Fall-through.
     case JSObject:
@@ -414,14 +385,11 @@ bool QScriptValuePrivate::isError()
 bool QScriptValuePrivate::isObject()
 {
     switch (m_state) {
 bool QScriptValuePrivate::isObject()
 {
     switch (m_state) {
-    case JSObject:
-        return true;
     case JSValue:
     case JSValue:
-        m_object = JSValueToObject(context(), value(), /* exception */ 0);
-        if (!m_object)
-            return false;
-        m_state = JSObject;
+        return refinedJSValue() == JSObject;
+    case JSObject:
         return true;
         return true;
+
     default:
         return false;
     }
     default:
         return false;
     }
@@ -431,10 +399,8 @@ bool QScriptValuePrivate::isFunction()
 {
     switch (m_state) {
     case JSValue:
 {
     switch (m_state) {
     case JSValue:
-        m_object = JSValueToObject(context(), value(), /* exception */ 0);
-        if (!m_object)
+        if (refinedJSValue() != JSObject)
             return false;
             return false;
-        m_state = JSObject;
         // Fall-through.
     case JSObject:
         return JSObjectIsFunction(context(), object());
         // Fall-through.
     case JSObject:
         return JSObjectIsFunction(context(), object());
@@ -453,13 +419,14 @@ QString QScriptValuePrivate::toString() const
     case CString:
         return m_string;
     case CNumber:
     case CString:
         return m_string;
     case CNumber:
-        return QString::number(m_number);
+        return QScriptConverter::toString(m_number);
     case CSpecial:
         return m_number == QScriptValue::NullValue ? QString::fromLatin1("null") : QString::fromLatin1("undefined");
     case JSValue:
     case CSpecial:
         return m_number == QScriptValue::NullValue ? QString::fromLatin1("null") : QString::fromLatin1("undefined");
     case JSValue:
-    case JSNative:
+    case JSPrimitive:
     case JSObject:
     case JSObject:
-        return QScriptConverter::toString(JSValueToStringCopy(context(), value(), /* exception */ 0));
+        JSRetainPtr<JSStringRef> ptr(Adopt, JSValueToStringCopy(context(), value(), /* exception */ 0));
+        return QScriptConverter::toString(ptr.get());
     }
 
     Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement.");
     }
 
     Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement.");
@@ -468,20 +435,30 @@ QString QScriptValuePrivate::toString() const
 
 qsreal QScriptValuePrivate::toNumber() const
 {
 
 qsreal QScriptValuePrivate::toNumber() const
 {
-    // TODO Check it.
     switch (m_state) {
     case JSValue:
     switch (m_state) {
     case JSValue:
-    case JSNative:
+    case JSPrimitive:
     case JSObject:
         return JSValueToNumber(context(), value(), /* exception */ 0);
     case CNumber:
     case JSObject:
         return JSValueToNumber(context(), value(), /* exception */ 0);
     case CNumber:
-    case CBool:
         return m_number;
         return m_number;
+    case CBool:
+        return m_number ? 1 : 0;
     case Invalid:
     case Invalid:
+        return 0;
     case CSpecial:
     case CSpecial:
-        return false;
+        return m_number == QScriptValue::NullValue ? 0 : qQNaN();
     case CString:
     case CString:
-        return m_string.isEmpty();
+        bool ok;
+        qsreal result = m_string.toDouble(&ok);
+        if (ok)
+            return result;
+        result = m_string.toInt(&ok, 0); // Try other bases.
+        if (ok)
+            return result;
+        if (m_string == "Infinity" || m_string == "-Infinity")
+            return qInf();
+        return m_string.length() ? qQNaN() : 0;
     }
 
     Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement.");
     }
 
     Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement.");
@@ -492,17 +469,19 @@ bool QScriptValuePrivate::toBool() const
 {
     switch (m_state) {
     case JSValue:
 {
     switch (m_state) {
     case JSValue:
-    case JSNative:
-    case JSObject:
+    case JSPrimitive:
         return JSValueToBoolean(context(), value());
         return JSValueToBoolean(context(), value());
+    case JSObject:
+        return true;
     case CNumber:
     case CNumber:
+        return !(qIsNaN(m_number) || !m_number);
     case CBool:
         return m_number;
     case Invalid:
     case CSpecial:
         return false;
     case CString:
     case CBool:
         return m_number;
     case Invalid:
     case CSpecial:
         return false;
     case CString:
-        return m_string.isEmpty();
+        return m_string.length();
     }
 
     Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement.");
     }
 
     Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement.");
@@ -511,26 +490,37 @@ bool QScriptValuePrivate::toBool() const
 
 qsreal QScriptValuePrivate::toInteger() const
 {
 
 qsreal QScriptValuePrivate::toInteger() const
 {
-    // TODO it is not true implementation!
-    return toNumber();
+    qsreal result = toNumber();
+    if (qIsNaN(result))
+        return 0;
+    if (qIsInf(result))
+        return result;
+    return (result > 0) ? qFloor(result) : -1 * qFloor(-result);
 }
 
 qint32 QScriptValuePrivate::toInt32() const
 {
 }
 
 qint32 QScriptValuePrivate::toInt32() const
 {
-    // TODO it is not true implementation!
-    return toNumber();
+    qsreal result = toInteger();
+    // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but
+    // some of these operation are invoked in toInteger subcall.
+    if (qIsInf(result))
+        return 0;
+    return result;
 }
 
 quint32 QScriptValuePrivate::toUInt32() const
 {
 }
 
 quint32 QScriptValuePrivate::toUInt32() const
 {
-    // TODO it is not true implementation!
-    return toNumber();
+    qsreal result = toInteger();
+    // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but
+    // some of these operation are invoked in toInteger subcall.
+    if (qIsInf(result))
+        return 0;
+    return result;
 }
 
 quint16 QScriptValuePrivate::toUInt16() const
 {
 }
 
 quint16 QScriptValuePrivate::toUInt16() const
 {
-    // TODO it is not true implementation!
-    return toNumber();
+    return toInt32();
 }
 
 
 }
 
 
@@ -606,7 +596,7 @@ bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine)
         return false;
     }
     m_engine = engine;
         return false;
     }
     m_engine = engine;
-    m_state = JSNative;
+    m_state = JSPrimitive;
     setValue(value);
     return true;
 }
     setValue(value);
     return true;
 }
@@ -615,12 +605,8 @@ QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const
 {
     switch (m_state) {
     case JSValue:
 {
     switch (m_state) {
     case JSValue:
-        m_object = JSValueToObject(context(), value(), /* exception */ 0);
-        if (!object()) {
-            m_state = JSValue;
+        if (refinedJSValue() != JSObject)
             return new QScriptValuePrivate;
             return new QScriptValuePrivate;
-        }
-        m_state = JSObject;
         // Fall-through.
     case JSObject:
         {
         // Fall-through.
     case JSObject:
         {
@@ -694,10 +680,30 @@ bool QScriptValuePrivate::inherits(const char* name)
 {
     Q_ASSERT(isJSBased());
     JSObjectRef globalObject = JSContextGetGlobalObject(context());
 {
     Q_ASSERT(isJSBased());
     JSObjectRef globalObject = JSContextGetGlobalObject(context());
-    JSValueRef error = JSObjectGetProperty(context(), globalObject, QScriptConverter::toString(name), 0);
+    JSStringRef errorAttrName = QScriptConverter::toString(name);
+    JSValueRef error = JSObjectGetProperty(context(), globalObject, errorAttrName, /* exception */ 0);
+    JSStringRelease(errorAttrName);
     return JSValueIsInstanceOfConstructor(context(), value(), JSValueToObject(context(), error, /* exception */ 0), /* exception */ 0);
 }
 
     return JSValueIsInstanceOfConstructor(context(), value(), JSValueToObject(context(), error, /* exception */ 0), /* exception */ 0);
 }
 
+/*!
+  \internal
+  Refines the state of this QScriptValuePrivate. Returns the new state.
+*/
+QScriptValuePrivate::State QScriptValuePrivate::refinedJSValue()
+{
+    Q_ASSERT(m_state == JSValue);
+    if (!JSValueIsObject(context(), value())) {
+        m_state = JSPrimitive;
+    } else {
+        m_state = JSObject;
+        // We are sure that value is an JSObject, so we can const_cast safely without
+        // calling JSC C API (JSValueToObject(context(), value(), /* exceptions */ 0)).
+        m_object = const_cast<JSObjectRef>(m_value);
+    }
+    return m_state;
+}
+
 /*!
   \internal
   Returns true if QSV have an engine associated.
 /*!
   \internal
   Returns true if QSV have an engine associated.
index 29749c0ba9f5096a57fb508f7f9f472bc96d25e3..efdfc509387ee3a6ebb7857df51444c06755d38b 100644 (file)
 
 #include <QtCore/qglobal.h>
 
 
 #include <QtCore/qglobal.h>
 
-#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
-#  if defined(QT_NODLL)
-#  elif defined(QT_MAKEDLL)        /* create a Qt DLL library */
-#    if defined(QT_BUILD_JAVASCRIPT_LIB)
-#      define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT
-#    else
-#      define Q_JAVASCRIPT_EXPORT Q_DECL_IMPORT
-#    endif
-#  elif defined(QT_DLL) /* use a Qt DLL library */
-#    define Q_JAVASCRIPT_EXPORT
+#if defined(QT_MAKEDLL)        /* create a Qt DLL library */
+#  if defined(QT_BUILD_JAVASCRIPT_LIB)
+#    define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT
+#  else
+#    define Q_JAVASCRIPT_EXPORT Q_DECL_IMPORT
 #  endif
 #  endif
+#elif defined(QT_DLL) /* use a Qt DLL library */
+#  define Q_JAVASCRIPT_EXPORT
 #endif
 
 #endif
 
-#if defined(QT_SHARED)
-#  define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT
-#else
-#  define Q_JAVASCRIPT_EXPORT
+#if !defined(Q_JAVASCRIPT_EXPORT)
+#  if defined(QT_SHARED)
+#    define Q_JAVASCRIPT_EXPORT Q_DECL_EXPORT
+#  else
+#    define Q_JAVASCRIPT_EXPORT
+#  endif
 #endif
 
 #endif
 #endif
 
 #endif
index 0dc09026d762ba74c8ff308644d9e38cffd846dc..d521dd89bdbeb42291f77c0997e9087ed491ab78 100644 (file)
@@ -1,6 +1,7 @@
 TEMPLATE = app
 TARGET = tst_qscriptengine
 QT += testlib
 TEMPLATE = app
 TARGET = tst_qscriptengine
 QT += testlib
+isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../..
 include(../tests.pri)
 
 SOURCES += tst_qscriptengine.cpp
 include(../tests.pri)
 
 SOURCES += tst_qscriptengine.cpp
index 37f3d11012d8dc9cd3c9aefdc2f0a4877db0d0cd..1ec9ad3f0c0979c6c756ff1ea183a375cb0e3f06 100644 (file)
@@ -18,6 +18,8 @@
 */
 
 #include "qscriptengine.h"
 */
 
 #include "qscriptengine.h"
+#include "qscriptprogram.h"
+#include "qscriptsyntaxcheckresult.h"
 #include "qscriptvalue.h"
 #include <QtTest/qtest.h>
 
 #include "qscriptvalue.h"
 #include <QtTest/qtest.h>
 
@@ -33,8 +35,15 @@ public slots:
     void cleanup() {}
 
 private slots:
     void cleanup() {}
 
 private slots:
+    void globalObject();
     void evaluate();
     void collectGarbage();
     void evaluate();
     void collectGarbage();
+    void reportAdditionalMemoryCost();
+    void nullValue();
+    void undefinedValue();
+    void evaluateProgram();
+    void checkSyntax_data();
+    void checkSyntax();
 };
 
 /* Evaluating a script that throw an unhandled exception should return an invalid value. */
 };
 
 /* Evaluating a script that throw an unhandled exception should return an invalid value. */
@@ -45,6 +54,17 @@ void tst_QScriptEngine::evaluate()
     QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value");
 }
 
     QVERIFY2(engine.evaluate("ping").isValid(), "Script throwing an unhandled exception should return an exception value");
 }
 
+void tst_QScriptEngine::globalObject()
+{
+    QScriptEngine engine;
+    QScriptValue global = engine.globalObject();
+    QScriptValue self = engine.evaluate("this");
+    QVERIFY(global.isObject());
+    QVERIFY(engine.globalObject().equals(engine.evaluate("this")));
+    QEXPECT_FAIL("", "strictlyEquals is broken - bug 36600 in bugs.webkit.org", Continue);
+    QVERIFY(engine.globalObject().strictlyEquals(self));
+}
+
 /* Test garbage collection, at least try to not crash. */
 void tst_QScriptEngine::collectGarbage()
 {
 /* Test garbage collection, at least try to not crash. */
 void tst_QScriptEngine::collectGarbage()
 {
@@ -54,5 +74,235 @@ void tst_QScriptEngine::collectGarbage()
     engine.collectGarbage();
     QCOMPARE(foo.call().toString(), QString::fromAscii("pong"));
 }
     engine.collectGarbage();
     QCOMPARE(foo.call().toString(), QString::fromAscii("pong"));
 }
+
+void tst_QScriptEngine::reportAdditionalMemoryCost()
+{
+    // There isn't any easy way to test the responsiveness of the GC;
+    // just try to call the function a few times with various sizes.
+    QScriptEngine eng;
+    for (int i = 0; i < 100; ++i) {
+        eng.reportAdditionalMemoryCost(0);
+        eng.reportAdditionalMemoryCost(10);
+        eng.reportAdditionalMemoryCost(1000);
+        eng.reportAdditionalMemoryCost(10000);
+        eng.reportAdditionalMemoryCost(100000);
+        eng.reportAdditionalMemoryCost(1000000);
+        eng.reportAdditionalMemoryCost(10000000);
+        eng.reportAdditionalMemoryCost(-1);
+        eng.reportAdditionalMemoryCost(-1000);
+        QScriptValue obj = eng.evaluate("new Object");
+        eng.collectGarbage();
+    }
+}
+
+void tst_QScriptEngine::nullValue()
+{
+    QScriptEngine engine;
+    QScriptValue value = engine.nullValue();
+    QVERIFY(value.isValid());
+    QVERIFY(value.isNull());
+}
+
+void tst_QScriptEngine::undefinedValue()
+{
+    QScriptEngine engine;
+    QScriptValue value = engine.undefinedValue();
+    QVERIFY(value.isValid());
+    QVERIFY(value.isUndefined());
+}
+
+void tst_QScriptEngine::evaluateProgram()
+{
+    QScriptEngine eng;
+    {
+        QString code("1 + 2");
+        QString fileName("hello.js");
+        int lineNumber = 123;
+        QScriptProgram program(code, fileName, lineNumber);
+        QVERIFY(!program.isNull());
+        QCOMPARE(program.sourceCode(), code);
+        QCOMPARE(program.fileName(), fileName);
+        QCOMPARE(program.firstLineNumber(), lineNumber);
+
+        QScriptValue expected = eng.evaluate(code);
+        for (int x = 0; x < 10; ++x) {
+            QScriptValue ret = eng.evaluate(program);
+            QVERIFY(ret.equals(expected));
+        }
+
+        // operator=
+        QScriptProgram sameProgram = program;
+        QVERIFY(sameProgram == program);
+        QVERIFY(eng.evaluate(sameProgram).equals(expected));
+
+        // copy constructor
+        QScriptProgram sameProgram2(program);
+        QVERIFY(sameProgram2 == program);
+        QVERIFY(eng.evaluate(sameProgram2).equals(expected));
+
+        QScriptProgram differentProgram("2 + 3");
+        QVERIFY(differentProgram != program);
+        QVERIFY(!eng.evaluate(differentProgram).equals(expected));
+    }
+
+    // Program that accesses variable in the scope
+    {
+        QScriptProgram program("a");
+        QVERIFY(!program.isNull());
+        {
+            QScriptValue ret = eng.evaluate(program);
+            QVERIFY(ret.isError());
+            QCOMPARE(ret.toString(), QString::fromLatin1("ReferenceError: Can't find variable: a"));
+        }
+        {
+            QScriptValue ret = eng.evaluate(program);
+            QVERIFY(ret.isError());
+        }
+        eng.evaluate("a = 456");
+        {
+            QScriptValue ret = eng.evaluate(program);
+            QVERIFY(!ret.isError());
+            QCOMPARE(ret.toNumber(), 456.0);
+        }
+    }
+
+    // Program that creates closure
+    {
+        QScriptProgram program("(function() { var count = 0; return function() { return count++; }; })");
+        QVERIFY(!program.isNull());
+        QScriptValue createCounter = eng.evaluate(program);
+        QVERIFY(createCounter.isFunction());
+        QScriptValue counter = createCounter.call();
+        QVERIFY(counter.isFunction());
+        {
+            QScriptValue ret = counter.call();
+            QVERIFY(ret.isNumber());
+        }
+        QScriptValue counter2 = createCounter.call();
+        QVERIFY(counter2.isFunction());
+        QVERIFY(!counter2.equals(counter));
+        {
+            QScriptValue ret = counter2.call();
+            QVERIFY(ret.isNumber());
+        }
+    }
+
+    // Same program run in different engines
+    {
+        QString code("1 + 2");
+        QScriptProgram program(code);
+        QVERIFY(!program.isNull());
+        double expected = eng.evaluate(program).toNumber();
+        for (int x = 0; x < 2; ++x) {
+            QScriptEngine eng2;
+            for (int y = 0; y < 2; ++y) {
+                double ret = eng2.evaluate(program).toNumber();
+                QCOMPARE(ret, expected);
+            }
+        }
+    }
+
+    // No program
+    {
+        QScriptProgram program;
+        QVERIFY(program.isNull());
+        QScriptValue ret = eng.evaluate(program);
+        QVERIFY(!ret.isValid());
+    }
+}
+
+void tst_QScriptEngine::checkSyntax_data()
+{
+    QTest::addColumn<QString>("code");
+    QTest::addColumn<int>("expectedState");
+    QTest::addColumn<int>("errorLineNumber");
+    QTest::addColumn<int>("errorColumnNumber");
+    QTest::addColumn<QString>("errorMessage");
+
+    QTest::newRow("0")
+        << QString("0") << int(QScriptSyntaxCheckResult::Valid)
+        << -1 << -1 << "";
+    QTest::newRow("if (")
+        << QString("if (\n") << int(QScriptSyntaxCheckResult::Intermediate)
+        << 1 << 4 << "";
+    QTest::newRow("if else")
+        << QString("\nif else") << int(QScriptSyntaxCheckResult::Error)
+        << 2 << 4 << "SyntaxError: Parse error";
+    QTest::newRow("{if}")
+            << QString("{\n{\nif\n}\n") << int(QScriptSyntaxCheckResult::Error)
+        << 4 << 1 << "SyntaxError: Parse error";
+    QTest::newRow("foo[")
+        << QString("foo[") << int(QScriptSyntaxCheckResult::Error)
+        << 1 << 4 << "SyntaxError: Parse error";
+    QTest::newRow("foo['bar']")
+        << QString("foo['bar']") << int(QScriptSyntaxCheckResult::Valid)
+        << -1 << -1 << "";
+
+    QTest::newRow("/*")
+        << QString("/*") << int(QScriptSyntaxCheckResult::Intermediate)
+        << 1 << 1 << "Unclosed comment at end of file";
+    QTest::newRow("/*\nMy comment")
+        << QString("/*\nMy comment") << int(QScriptSyntaxCheckResult::Intermediate)
+        << 1 << 1 << "Unclosed comment at end of file";
+    QTest::newRow("/*\nMy comment */\nfoo = 10")
+        << QString("/*\nMy comment */\nfoo = 10") << int(QScriptSyntaxCheckResult::Valid)
+        << -1 << -1 << "";
+    QTest::newRow("foo = 10 /*")
+        << QString("foo = 10 /*") << int(QScriptSyntaxCheckResult::Intermediate)
+        << -1 << -1 << "";
+    QTest::newRow("foo = 10; /*")
+        << QString("foo = 10; /*") << int(QScriptSyntaxCheckResult::Intermediate)
+        << 1 << 11 << "Expected `end of file'";
+    QTest::newRow("foo = 10 /* My comment */")
+        << QString("foo = 10 /* My comment */") << int(QScriptSyntaxCheckResult::Valid)
+        << -1 << -1 << "";
+
+    QTest::newRow("/=/")
+        << QString("/=/") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << "";
+    QTest::newRow("/=/g")
+        << QString("/=/g") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << "";
+    QTest::newRow("/a/")
+        << QString("/a/") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << "";
+    QTest::newRow("/a/g")
+        << QString("/a/g") << int(QScriptSyntaxCheckResult::Valid) << -1 << -1 << "";
+}
+
+void tst_QScriptEngine::checkSyntax()
+{
+    QFETCH(QString, code);
+    QFETCH(int, expectedState);
+    QFETCH(int, errorLineNumber);
+    QFETCH(int, errorColumnNumber);
+    QFETCH(QString, errorMessage);
+
+    QScriptSyntaxCheckResult result = QScriptEngine::checkSyntax(code);
+
+    // assignment
+    {
+        QScriptSyntaxCheckResult copy = result;
+        QCOMPARE(copy.state(), result.state());
+        QCOMPARE(copy.errorLineNumber(), result.errorLineNumber());
+        QCOMPARE(copy.errorColumnNumber(), result.errorColumnNumber());
+        QCOMPARE(copy.errorMessage(), result.errorMessage());
+    }
+    {
+        QScriptSyntaxCheckResult copy(result);
+        QCOMPARE(copy.state(), result.state());
+        QCOMPARE(copy.errorLineNumber(), result.errorLineNumber());
+        QCOMPARE(copy.errorColumnNumber(), result.errorColumnNumber());
+        QCOMPARE(copy.errorMessage(), result.errorMessage());
+    }
+
+    if (expectedState == QScriptSyntaxCheckResult::Intermediate)
+        QEXPECT_FAIL("", "QScriptSyntaxCheckResult::state() doesn't return the Intermediate state", Abort);
+    QCOMPARE(result.state(), QScriptSyntaxCheckResult::State(expectedState));
+    QCOMPARE(result.errorLineNumber(), errorLineNumber);
+    if (expectedState != QScriptSyntaxCheckResult::Valid && errorColumnNumber != 1)
+            QEXPECT_FAIL("", "QScriptSyntaxCheckResult::errorColumnNumber() doesn't return correct value", Continue);
+    QCOMPARE(result.errorColumnNumber(), errorColumnNumber);
+    QCOMPARE(result.errorMessage(), errorMessage);
+}
+
+
 QTEST_MAIN(tst_QScriptEngine)
 #include "tst_qscriptengine.moc"
 QTEST_MAIN(tst_QScriptEngine)
 #include "tst_qscriptengine.moc"
diff --git a/qt/tests/qscriptstring/qscriptstring.pro b/qt/tests/qscriptstring/qscriptstring.pro
new file mode 100644 (file)
index 0000000..5ad9b7c
--- /dev/null
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = tst_qscriptstring
+QT += testlib
+include(../tests.pri)
+
+SOURCES += tst_qscriptstring.cpp
+
diff --git a/qt/tests/qscriptstring/tst_qscriptstring.cpp b/qt/tests/qscriptstring/tst_qscriptstring.cpp
new file mode 100644 (file)
index 0000000..ff31835
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 tst_qscriptstring_h
+#define tst_qscriptstring_h
+
+#include "qscriptengine.h"
+#include "qscriptstring.h"
+#include <QtCore/qhash.h>
+#include <QtTest/QtTest>
+
+class tst_QScriptString : public QObject {
+    Q_OBJECT
+
+public:
+    tst_QScriptString();
+    virtual ~tst_QScriptString();
+
+private slots:
+    void test();
+    void hash();
+    void toArrayIndex_data();
+    void toArrayIndex();
+};
+
+tst_QScriptString::tst_QScriptString()
+{
+}
+
+tst_QScriptString::~tst_QScriptString()
+{
+}
+
+void tst_QScriptString::test()
+{
+    QScriptEngine eng;
+    {
+        QScriptString str;
+        QVERIFY(!str.isValid());
+        QVERIFY(str == str);
+        QVERIFY(!(str != str));
+        QVERIFY(str.toString().isNull());
+
+        QScriptString str1(str);
+        QVERIFY(!str1.isValid());
+
+        QScriptString str2 = str;
+        QVERIFY(!str2.isValid());
+
+        QCOMPARE(str.toArrayIndex(), quint32(0xffffffff));
+    }
+    for (int x = 0; x < 2; ++x) {
+        QString ciao = QString::fromLatin1("ciao");
+        QScriptString str = eng.toStringHandle(ciao);
+        QVERIFY(str.isValid());
+        QVERIFY(str == str);
+        QVERIFY(!(str != str));
+        QCOMPARE(str.toString(), ciao);
+
+        QScriptString str1(str);
+        QCOMPARE(str, str1);
+
+        QScriptString str2 = str;
+        QCOMPARE(str, str2);
+
+        QScriptString str3 = eng.toStringHandle(ciao);
+        QVERIFY(str3.isValid());
+        QCOMPARE(str, str3);
+
+        eng.collectGarbage();
+
+        QVERIFY(str.isValid());
+        QCOMPARE(str.toString(), ciao);
+        QVERIFY(str1.isValid());
+        QCOMPARE(str1.toString(), ciao);
+        QVERIFY(str2.isValid());
+        QCOMPARE(str2.toString(), ciao);
+        QVERIFY(str3.isValid());
+        QCOMPARE(str3.toString(), ciao);
+    }
+    {
+        QScriptEngine* eng2 = new QScriptEngine;
+        QString one = QString::fromLatin1("one");
+        QString two = QString::fromLatin1("two");
+        QScriptString oneInterned = eng2->toStringHandle(one);
+        QCOMPARE(oneInterned.toString(), one);
+        QScriptString twoInterned = eng2->toStringHandle(two);
+        QCOMPARE(twoInterned.toString(), two);
+        QVERIFY(oneInterned != twoInterned);
+        QVERIFY(!(oneInterned == twoInterned));
+
+        delete eng2;
+    }
+}
+
+void tst_QScriptString::hash()
+{
+    QScriptEngine engine;
+    QHash<QScriptString, int> stringToInt;
+    QScriptString foo = engine.toStringHandle("foo");
+
+    QScriptString bar = engine.toStringHandle("bar");
+    QVERIFY(!stringToInt.contains(foo));
+    for (int i = 0; i < 1000000; ++i)
+        stringToInt.insert(foo, 123);
+    QCOMPARE(stringToInt.value(foo), 123);
+    QVERIFY(!stringToInt.contains(bar));
+    stringToInt.insert(bar, 456);
+    QCOMPARE(stringToInt.value(bar), 456);
+    QCOMPARE(stringToInt.value(foo), 123);
+}
+
+void tst_QScriptString::toArrayIndex_data()
+{
+    QTest::addColumn<QString>("input");
+    QTest::addColumn<bool>("expectSuccess");
+    QTest::addColumn<quint32>("expectedIndex");
+    QTest::newRow("foo") << QString::fromLatin1("foo") << false << quint32(0xffffffff);
+    QTest::newRow("empty") << QString::fromLatin1("") << false << quint32(0xffffffff);
+    QTest::newRow("0") << QString::fromLatin1("0") << true << quint32(0);
+    QTest::newRow("00") << QString::fromLatin1("00") << false << quint32(0xffffffff);
+    QTest::newRow("1") << QString::fromLatin1("1") << true << quint32(1);
+    QTest::newRow("123") << QString::fromLatin1("123") << true << quint32(123);
+    QTest::newRow("-1") << QString::fromLatin1("-1") << false << quint32(0xffffffff);
+    QTest::newRow("0a") << QString::fromLatin1("0a") << false << quint32(0xffffffff);
+    QTest::newRow("0x1") << QString::fromLatin1("0x1") << false << quint32(0xffffffff);
+    QTest::newRow("01") << QString::fromLatin1("01") << false << quint32(0xffffffff);
+    QTest::newRow("101a") << QString::fromLatin1("101a") << false << quint32(0xffffffff);
+    QTest::newRow("4294967294") << QString::fromLatin1("4294967294") << true << quint32(0xfffffffe);
+    QTest::newRow("4294967295") << QString::fromLatin1("4294967295") << false << quint32(0xffffffff);
+    QTest::newRow("11111111111") << QString::fromLatin1("11111111111") << false << quint32(0xffffffff);
+    QTest::newRow("0.0") << QString::fromLatin1("0.0") << false << quint32(0xffffffff);
+    QTest::newRow("1.0") << QString::fromLatin1("1.0") << false << quint32(0xffffffff);
+    QTest::newRow("1.5") << QString::fromLatin1("1.5") << false << quint32(0xffffffff);
+    QTest::newRow("1.") << QString::fromLatin1("1.") << false << quint32(0xffffffff);
+    QTest::newRow(".1") << QString::fromLatin1(".1") << false << quint32(0xffffffff);
+    QTest::newRow("1e0") << QString::fromLatin1("1e0") << false << quint32(0xffffffff);
+}
+
+void tst_QScriptString::toArrayIndex()
+{
+    QFETCH(QString, input);
+    QFETCH(bool, expectSuccess);
+    QFETCH(quint32, expectedIndex);
+    QScriptEngine engine;
+    for (int x = 0; x < 2; ++x) {
+        bool isArrayIndex;
+        bool* ptr = (!x) ? &isArrayIndex : (bool*)0;
+        quint32 result = engine.toStringHandle(input).toArrayIndex(ptr);
+        if (!x)
+            QCOMPARE(isArrayIndex, expectSuccess);
+        QCOMPARE(result, expectedIndex);
+    }
+}
+
+QTEST_MAIN(tst_QScriptString)
+#include "tst_qscriptstring.moc"
+
+#endif // tst_qscriptstring_h
index 1ce5bc3e8322870e39e1c976da92b066ad171682..35cc17da9083768a845bae214b5ba1ce926e8557 100644 (file)
@@ -1,7 +1,12 @@
 TEMPLATE = app
 TARGET = tst_qscriptvalue
 QT += testlib
 TEMPLATE = app
 TARGET = tst_qscriptvalue
 QT += testlib
+isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../..
 include(../tests.pri)
 
 include(../tests.pri)
 
-SOURCES += tst_qscriptvalue.cpp
+SOURCES += \
+    tst_qscriptvalue.cpp \
+    tst_qscriptvalue_generated.cpp
 
 
+HEADERS += \
+    tst_qscriptvalue.h
index 336a1a6982529fb8776ffbd2d224f6e197a22f5b..82f09014fa81a9d7f3300205a1fc5eef1c6f781b 100644 (file)
     Boston, MA 02110-1301, USA.
 */
 
     Boston, MA 02110-1301, USA.
 */
 
-#include "qscriptengine.h"
-#include "qscriptvalue.h"
-#include <QtTest/qtest.h>
-
-Q_DECLARE_METATYPE(QScriptValue*);
-Q_DECLARE_METATYPE(QScriptValue);
-
-class tst_QScriptValue : public QObject {
-    Q_OBJECT
-
-public:
-    tst_QScriptValue() {}
-    virtual ~tst_QScriptValue() {}
-
-private slots:
-    void toString_data();
-    void toString();
-    void copyConstructor_data();
-    void copyConstructor();
-    void assignOperator_data();
-    void assignOperator();
-    void dataSharing();
-    void constructors_data();
-    void constructors();
-    void call();
-
-    // copied from Qt's QtScript.
-    void ctor();
-};
+#include "tst_qscriptvalue.h"
+#include <QtCore/qnumeric.h>
+
+tst_QScriptValue::tst_QScriptValue()
+    : engine(0)
+{
+}
+
+tst_QScriptValue::~tst_QScriptValue()
+{
+    delete engine;
+}
+
+void tst_QScriptValue::dataHelper(InitDataFunction init, DefineDataFunction define)
+{
+    QTest::addColumn<QString>("__expression__");
+    (this->*init)();
+    QHash<QString, QScriptValue>::const_iterator it;
+    for (it = m_values.constBegin(); it != m_values.constEnd(); ++it) {
+        m_currentExpression = it.key();
+        (this->*define)(it.key().toLatin1());
+    }
+    m_currentExpression = QString();
+}
+
+QTestData& tst_QScriptValue::newRow(const char* tag)
+{
+    return QTest::newRow(tag) << m_currentExpression;
+}
+
+void tst_QScriptValue::testHelper(TestFunction fun)
+{
+    QFETCH(QString, __expression__);
+    QScriptValue value = m_values.value(__expression__);
+    (this->*fun)(__expression__.toLatin1(), value);
+}
+
 
 void tst_QScriptValue::ctor()
 {
 
 void tst_QScriptValue::ctor()
 {
@@ -53,7 +61,7 @@ void tst_QScriptValue::ctor()
     {
         QScriptValue v;
         QCOMPARE(v.isValid(), false);
     {
         QScriptValue v;
         QCOMPARE(v.isValid(), false);
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     {
         QScriptValue v(&eng, QScriptValue::UndefinedValue);
     }
     {
         QScriptValue v(&eng, QScriptValue::UndefinedValue);
@@ -168,14 +176,14 @@ void tst_QScriptValue::ctor()
         QCOMPARE(v.isValid(), true);
         QCOMPARE(v.isUndefined(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.isValid(), true);
         QCOMPARE(v.isUndefined(), true);
         QCOMPARE(v.isObject(), false);
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     {
         QScriptValue v(QScriptValue::NullValue);
         QCOMPARE(v.isValid(), true);
         QCOMPARE(v.isNull(), true);
         QCOMPARE(v.isObject(), false);
     }
     {
         QScriptValue v(QScriptValue::NullValue);
         QCOMPARE(v.isValid(), true);
         QCOMPARE(v.isNull(), true);
         QCOMPARE(v.isObject(), false);
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     {
         QScriptValue v(false);
     }
     {
         QScriptValue v(false);
@@ -184,7 +192,7 @@ void tst_QScriptValue::ctor()
         QCOMPARE(v.isBool(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toBoolean(), false);
         QCOMPARE(v.isBool(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toBoolean(), false);
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     {
         QScriptValue v(int(1));
     }
     {
         QScriptValue v(int(1));
@@ -192,7 +200,7 @@ void tst_QScriptValue::ctor()
         QCOMPARE(v.isNumber(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toNumber(), 1.0);
         QCOMPARE(v.isNumber(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toNumber(), 1.0);
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     {
         QScriptValue v(uint(1));
     }
     {
         QScriptValue v(uint(1));
@@ -200,7 +208,7 @@ void tst_QScriptValue::ctor()
         QCOMPARE(v.isNumber(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toNumber(), 1.0);
         QCOMPARE(v.isNumber(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toNumber(), 1.0);
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     {
         QScriptValue v(1.0);
     }
     {
         QScriptValue v(1.0);
@@ -208,7 +216,7 @@ void tst_QScriptValue::ctor()
         QCOMPARE(v.isNumber(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toNumber(), 1.0);
         QCOMPARE(v.isNumber(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toNumber(), 1.0);
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     {
         QScriptValue v("ciao");
     }
     {
         QScriptValue v("ciao");
@@ -216,7 +224,7 @@ void tst_QScriptValue::ctor()
         QCOMPARE(v.isString(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toString(), QLatin1String("ciao"));
         QCOMPARE(v.isString(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toString(), QLatin1String("ciao"));
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     {
         QScriptValue v(QString("ciao"));
     }
     {
         QScriptValue v(QString("ciao"));
@@ -224,19 +232,19 @@ void tst_QScriptValue::ctor()
         QCOMPARE(v.isString(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toString(), QLatin1String("ciao"));
         QCOMPARE(v.isString(), true);
         QCOMPARE(v.isObject(), false);
         QCOMPARE(v.toString(), QLatin1String("ciao"));
-        QCOMPARE(v.engine(), (QScriptEngine *)0);
+        QCOMPARE(v.engine(), (QScriptEngine*)0);
     }
     // copy constructor, operator=
     {
         QScriptValue v(1.0);
         QScriptValue v2(v);
         QCOMPARE(v2.strictlyEquals(v), true);
     }
     // copy constructor, operator=
     {
         QScriptValue v(1.0);
         QScriptValue v2(v);
         QCOMPARE(v2.strictlyEquals(v), true);
-        QCOMPARE(v2.engine(), (QScriptEngine *)0);
+        QCOMPARE(v2.engine(), (QScriptEngine*)0);
 
         QScriptValue v3(v);
         QCOMPARE(v3.strictlyEquals(v), true);
         QCOMPARE(v3.strictlyEquals(v2), true);
 
         QScriptValue v3(v);
         QCOMPARE(v3.strictlyEquals(v), true);
         QCOMPARE(v3.strictlyEquals(v2), true);
-        QCOMPARE(v3.engine(), (QScriptEngine *)0);
+        QCOMPARE(v3.engine(), (QScriptEngine*)0);
 
         QScriptValue v4(2.0);
         QCOMPARE(v4.strictlyEquals(v), false);
 
         QScriptValue v4(2.0);
         QCOMPARE(v4.strictlyEquals(v), false);
@@ -266,7 +274,7 @@ void tst_QScriptValue::ctor()
     QVERIFY(QScriptValue(0, QString("ciao")).isString());
 }
 
     QVERIFY(QScriptValue(0, QString("ciao")).isString());
 }
 
-void tst_QScriptValue::toString_data()
+void tst_QScriptValue::toStringSimple_data()
 {
     QTest::addColumn<QString>("code");
     QTest::addColumn<QString>("result");
 {
     QTest::addColumn<QString>("code");
     QTest::addColumn<QString>("result");
@@ -281,7 +289,7 @@ void tst_QScriptValue::toString_data()
 }
 
 /* Test conversion to string from different JSC types */
 }
 
 /* Test conversion to string from different JSC types */
-void tst_QScriptValue::toString()
+void tst_QScriptValue::toStringSimple()
 {
     QFETCH(QString, code);
     QFETCH(QString, result);
 {
     QFETCH(QString, code);
     QFETCH(QString, result);
@@ -423,5 +431,5 @@ void tst_QScriptValue::call()
     QVERIFY(incr.call().isValid()); // Exception.
 }
 
     QVERIFY(incr.call().isValid()); // Exception.
 }
 
+
 QTEST_MAIN(tst_QScriptValue)
 QTEST_MAIN(tst_QScriptValue)
-#include "tst_qscriptvalue.moc"
diff --git a/qt/tests/qscriptvalue/tst_qscriptvalue.h b/qt/tests/qscriptvalue/tst_qscriptvalue.h
new file mode 100644 (file)
index 0000000..28154a9
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 tst_qscriptvalue_h
+#define tst_qscriptvalue_h
+
+#include "qscriptengine.h"
+#include "qscriptvalue.h"
+#include <QtCore/qnumeric.h>
+#include <QtTest/qtest.h>
+
+Q_DECLARE_METATYPE(QScriptValue*);
+Q_DECLARE_METATYPE(QScriptValue);
+
+class tst_QScriptValue : public QObject {
+    Q_OBJECT
+
+public:
+    tst_QScriptValue();
+    virtual ~tst_QScriptValue();
+
+private slots:
+    void toStringSimple_data();
+    void toStringSimple();
+    void copyConstructor_data();
+    void copyConstructor();
+    void assignOperator_data();
+    void assignOperator();
+    void dataSharing();
+    void constructors_data();
+    void constructors();
+    void call();
+    void ctor();
+
+    // Generated test functions.
+    void isBool_data();
+    void isBool();
+
+    void isBoolean_data();
+    void isBoolean();
+
+    void isNumber_data();
+    void isNumber();
+
+    void isFunction_data();
+    void isFunction();
+
+    void isNull_data();
+    void isNull();
+
+    void isObject_data();
+    void isObject();
+
+    void isString_data();
+    void isString();
+
+    void isUndefined_data();
+    void isUndefined();
+
+    void isValid_data();
+    void isValid();
+
+    void toString_data();
+    void toString();
+
+    void toNumber_data();
+    void toNumber();
+
+    void toBool_data();
+    void toBool();
+
+    void toBoolean_data();
+    void toBoolean();
+
+    void toInteger_data();
+    void toInteger();
+
+    void toInt32_data();
+    void toInt32();
+
+    void toUInt32_data();
+    void toUInt32();
+
+    void toUInt16_data();
+    void toUInt16();
+
+private:
+    typedef void (tst_QScriptValue::*InitDataFunction)();
+    typedef void (tst_QScriptValue::*DefineDataFunction)(const char*);
+    void dataHelper(InitDataFunction init, DefineDataFunction define);
+    QTestData& newRow(const char* tag);
+
+    typedef void (tst_QScriptValue::*TestFunction)(const char*, const QScriptValue&);
+    void testHelper(TestFunction fun);
+
+    // Generated functions
+
+    void initScriptValues();
+
+    void isBool_initData();
+    void isBool_makeData(const char* expr);
+    void isBool_test(const char* expr, const QScriptValue& value);
+
+    void isBoolean_initData();
+    void isBoolean_makeData(const char* expr);
+    void isBoolean_test(const char* expr, const QScriptValue& value);
+
+    void isNumber_initData();
+    void isNumber_makeData(const char* expr);
+    void isNumber_test(const char* expr, const QScriptValue&);
+
+    void isFunction_initData();
+    void isFunction_makeData(const char* expr);
+    void isFunction_test(const char* expr, const QScriptValue& value);
+
+    void isNull_initData();
+    void isNull_makeData(const char* expr);
+    void isNull_test(const char* expr, const QScriptValue& value);
+
+    void isObject_initData();
+    void isObject_makeData(const char* expr);
+    void isObject_test(const char* expr, const QScriptValue& value);
+
+    void isString_initData();
+    void isString_makeData(const char* expr);
+    void isString_test(const char* expr, const QScriptValue& value);
+
+    void isUndefined_initData();
+    void isUndefined_makeData(const char* expr);
+    void isUndefined_test(const char* expr, const QScriptValue& value);
+
+    void isValid_initData();
+    void isValid_makeData(const char* expr);
+    void isValid_test(const char* expr, const QScriptValue& value);
+
+    void toString_initData();
+    void toString_makeData(const char*);
+    void toString_test(const char*, const QScriptValue&);
+
+    void toNumber_initData();
+    void toNumber_makeData(const char*);
+    void toNumber_test(const char*, const QScriptValue&);
+
+    void toBool_initData();
+    void toBool_makeData(const char*);
+    void toBool_test(const char*, const QScriptValue&);
+
+    void toBoolean_initData();
+    void toBoolean_makeData(const char*);
+    void toBoolean_test(const char*, const QScriptValue&);
+
+    void toInteger_initData();
+    void toInteger_makeData(const char*);
+    void toInteger_test(const char*, const QScriptValue&);
+
+    void toInt32_initData();
+    void toInt32_makeData(const char*);
+    void toInt32_test(const char*, const QScriptValue&);
+
+    void toUInt32_initData();
+    void toUInt32_makeData(const char*);
+    void toUInt32_test(const char*, const QScriptValue&);
+
+    void toUInt16_initData();
+    void toUInt16_makeData(const char*);
+    void toUInt16_test(const char*, const QScriptValue&);
+
+private:
+    QScriptEngine* engine;
+    QHash<QString, QScriptValue> m_values;
+    QString m_currentExpression;
+};
+
+#define DEFINE_TEST_FUNCTION(name) \
+void tst_QScriptValue::name##_data() { dataHelper(&tst_QScriptValue::name##_initData, &tst_QScriptValue::name##_makeData); } \
+void tst_QScriptValue::name() { testHelper(&tst_QScriptValue::name##_test); }
+
+
+
+#endif // tst_qscriptvalue_h
diff --git a/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp b/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp
new file mode 100644 (file)
index 0000000..970c960
--- /dev/null
@@ -0,0 +1,1922 @@
+/*
+    Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+    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 "tst_qscriptvalue.h"
+
+#define DEFINE_TEST_VALUE(expr) m_values.insert(QString::fromLatin1(#expr), expr)
+
+void tst_QScriptValue::initScriptValues()
+{
+    m_values.clear();
+    if (engine)
+        delete engine;
+    engine = new QScriptEngine;
+    DEFINE_TEST_VALUE(QScriptValue());
+    DEFINE_TEST_VALUE(QScriptValue(QScriptValue::UndefinedValue));
+    DEFINE_TEST_VALUE(QScriptValue(QScriptValue::NullValue));
+    DEFINE_TEST_VALUE(QScriptValue(true));
+    DEFINE_TEST_VALUE(QScriptValue(false));
+    DEFINE_TEST_VALUE(QScriptValue(int(122)));
+    DEFINE_TEST_VALUE(QScriptValue(uint(124)));
+    DEFINE_TEST_VALUE(QScriptValue(0));
+    DEFINE_TEST_VALUE(QScriptValue(0.0));
+    DEFINE_TEST_VALUE(QScriptValue(123.0));
+    DEFINE_TEST_VALUE(QScriptValue(6.37e-8));
+    DEFINE_TEST_VALUE(QScriptValue(-6.37e-8));
+    DEFINE_TEST_VALUE(QScriptValue(0x43211234));
+    DEFINE_TEST_VALUE(QScriptValue(0x10000));
+    DEFINE_TEST_VALUE(QScriptValue(0x10001));
+    DEFINE_TEST_VALUE(QScriptValue(qSNaN()));
+    DEFINE_TEST_VALUE(QScriptValue(qQNaN()));
+    DEFINE_TEST_VALUE(QScriptValue(qInf()));
+    DEFINE_TEST_VALUE(QScriptValue(-qInf()));
+    DEFINE_TEST_VALUE(QScriptValue("NaN"));
+    DEFINE_TEST_VALUE(QScriptValue("Infinity"));
+    DEFINE_TEST_VALUE(QScriptValue("-Infinity"));
+    DEFINE_TEST_VALUE(QScriptValue("ciao"));
+    DEFINE_TEST_VALUE(QScriptValue(QString::fromLatin1("ciao")));
+    DEFINE_TEST_VALUE(QScriptValue(QString("")));
+    DEFINE_TEST_VALUE(QScriptValue(QString()));
+    DEFINE_TEST_VALUE(QScriptValue(QString("0")));
+    DEFINE_TEST_VALUE(QScriptValue(QString("123")));
+    DEFINE_TEST_VALUE(QScriptValue(QString("12.4")));
+    DEFINE_TEST_VALUE(QScriptValue(0, QScriptValue::UndefinedValue));
+    DEFINE_TEST_VALUE(QScriptValue(0, QScriptValue::NullValue));
+    DEFINE_TEST_VALUE(QScriptValue(0, true));
+    DEFINE_TEST_VALUE(QScriptValue(0, false));
+    DEFINE_TEST_VALUE(QScriptValue(0, int(122)));
+    DEFINE_TEST_VALUE(QScriptValue(0, uint(124)));
+    DEFINE_TEST_VALUE(QScriptValue(0, 0));
+    DEFINE_TEST_VALUE(QScriptValue(0, 0.0));
+    DEFINE_TEST_VALUE(QScriptValue(0, 123.0));
+    DEFINE_TEST_VALUE(QScriptValue(0, 6.37e-8));
+    DEFINE_TEST_VALUE(QScriptValue(0, -6.37e-8));
+    DEFINE_TEST_VALUE(QScriptValue(0, 0x43211234));
+    DEFINE_TEST_VALUE(QScriptValue(0, 0x10000));
+    DEFINE_TEST_VALUE(QScriptValue(0, 0x10001));
+    DEFINE_TEST_VALUE(QScriptValue(0, qSNaN()));
+    DEFINE_TEST_VALUE(QScriptValue(0, qQNaN()));
+    DEFINE_TEST_VALUE(QScriptValue(0, qInf()));
+    DEFINE_TEST_VALUE(QScriptValue(0, -qInf()));
+    DEFINE_TEST_VALUE(QScriptValue(0, "NaN"));
+    DEFINE_TEST_VALUE(QScriptValue(0, "Infinity"));
+    DEFINE_TEST_VALUE(QScriptValue(0, "-Infinity"));
+    DEFINE_TEST_VALUE(QScriptValue(0, "ciao"));
+    DEFINE_TEST_VALUE(QScriptValue(0, QString::fromLatin1("ciao")));
+    DEFINE_TEST_VALUE(QScriptValue(0, QString("")));
+    DEFINE_TEST_VALUE(QScriptValue(0, QString()));
+    DEFINE_TEST_VALUE(QScriptValue(0, QString("0")));
+    DEFINE_TEST_VALUE(QScriptValue(0, QString("123")));
+    DEFINE_TEST_VALUE(QScriptValue(0, QString("12.3")));
+    DEFINE_TEST_VALUE(QScriptValue(engine, QScriptValue::UndefinedValue));
+    DEFINE_TEST_VALUE(QScriptValue(engine, QScriptValue::NullValue));
+    DEFINE_TEST_VALUE(QScriptValue(engine, true));
+    DEFINE_TEST_VALUE(QScriptValue(engine, false));
+    DEFINE_TEST_VALUE(QScriptValue(engine, int(122)));
+    DEFINE_TEST_VALUE(QScriptValue(engine, uint(124)));
+    DEFINE_TEST_VALUE(QScriptValue(engine, 0));
+    DEFINE_TEST_VALUE(QScriptValue(engine, 0.0));
+    DEFINE_TEST_VALUE(QScriptValue(engine, 123.0));
+    DEFINE_TEST_VALUE(QScriptValue(engine, 6.37e-8));
+    DEFINE_TEST_VALUE(QScriptValue(engine, -6.37e-8));
+    DEFINE_TEST_VALUE(QScriptValue(engine, 0x43211234));
+    DEFINE_TEST_VALUE(QScriptValue(engine, 0x10000));
+    DEFINE_TEST_VALUE(QScriptValue(engine, 0x10001));
+    DEFINE_TEST_VALUE(QScriptValue(engine, qSNaN()));
+    DEFINE_TEST_VALUE(QScriptValue(engine, qQNaN()));
+    DEFINE_TEST_VALUE(QScriptValue(engine, qInf()));
+    DEFINE_TEST_VALUE(QScriptValue(engine, -qInf()));
+    DEFINE_TEST_VALUE(QScriptValue(engine, "NaN"));
+    DEFINE_TEST_VALUE(QScriptValue(engine, "Infinity"));
+    DEFINE_TEST_VALUE(QScriptValue(engine, "-Infinity"));
+    DEFINE_TEST_VALUE(QScriptValue(engine, "ciao"));
+    DEFINE_TEST_VALUE(QScriptValue(engine, QString::fromLatin1("ciao")));
+    DEFINE_TEST_VALUE(QScriptValue(engine, QString("")));
+    DEFINE_TEST_VALUE(QScriptValue(engine, QString()));
+    DEFINE_TEST_VALUE(QScriptValue(engine, QString("0")));
+    DEFINE_TEST_VALUE(QScriptValue(engine, QString("123")));
+    DEFINE_TEST_VALUE(QScriptValue(engine, QString("1.23")));
+    DEFINE_TEST_VALUE(engine->evaluate("[]"));
+    DEFINE_TEST_VALUE(engine->evaluate("{}"));
+    DEFINE_TEST_VALUE(engine->evaluate("Object.prototype"));
+    DEFINE_TEST_VALUE(engine->evaluate("Date.prototype"));
+    DEFINE_TEST_VALUE(engine->evaluate("Array.prototype"));
+    DEFINE_TEST_VALUE(engine->evaluate("Function.prototype"));
+    DEFINE_TEST_VALUE(engine->evaluate("Error.prototype"));
+    DEFINE_TEST_VALUE(engine->evaluate("Object"));
+    DEFINE_TEST_VALUE(engine->evaluate("Array"));
+    DEFINE_TEST_VALUE(engine->evaluate("Number"));
+    DEFINE_TEST_VALUE(engine->evaluate("Function"));
+    DEFINE_TEST_VALUE(engine->evaluate("(function() { return 1; })"));
+    DEFINE_TEST_VALUE(engine->evaluate("(function() { return 'ciao'; })"));
+    DEFINE_TEST_VALUE(engine->evaluate("(function() { throw new Error('foo'); })"));
+    DEFINE_TEST_VALUE(engine->evaluate("/foo/"));
+    DEFINE_TEST_VALUE(engine->evaluate("new Object()"));
+    DEFINE_TEST_VALUE(engine->evaluate("new Array()"));
+    DEFINE_TEST_VALUE(engine->evaluate("new Error()"));
+    DEFINE_TEST_VALUE(engine->evaluate("a = new Object(); a.foo = 22; a.foo"));
+    DEFINE_TEST_VALUE(engine->evaluate("Undefined"));
+    DEFINE_TEST_VALUE(engine->evaluate("Null"));
+    DEFINE_TEST_VALUE(engine->evaluate("True"));
+    DEFINE_TEST_VALUE(engine->evaluate("False"));
+    DEFINE_TEST_VALUE(engine->evaluate("undefined"));
+    DEFINE_TEST_VALUE(engine->evaluate("null"));
+    DEFINE_TEST_VALUE(engine->evaluate("true"));
+    DEFINE_TEST_VALUE(engine->evaluate("false"));
+    DEFINE_TEST_VALUE(engine->evaluate("122"));
+    DEFINE_TEST_VALUE(engine->evaluate("124"));
+    DEFINE_TEST_VALUE(engine->evaluate("0"));
+    DEFINE_TEST_VALUE(engine->evaluate("0.0"));
+    DEFINE_TEST_VALUE(engine->evaluate("123.0"));
+    DEFINE_TEST_VALUE(engine->evaluate("6.37e-8"));
+    DEFINE_TEST_VALUE(engine->evaluate("-6.37e-8"));
+    DEFINE_TEST_VALUE(engine->evaluate("0x43211234"));
+    DEFINE_TEST_VALUE(engine->evaluate("0x10000"));
+    DEFINE_TEST_VALUE(engine->evaluate("0x10001"));
+    DEFINE_TEST_VALUE(engine->evaluate("NaN"));
+    DEFINE_TEST_VALUE(engine->evaluate("Infinity"));
+    DEFINE_TEST_VALUE(engine->evaluate("-Infinity"));
+    DEFINE_TEST_VALUE(engine->evaluate("'ciao'"));
+    DEFINE_TEST_VALUE(engine->evaluate("''"));
+    DEFINE_TEST_VALUE(engine->evaluate("'0'"));
+    DEFINE_TEST_VALUE(engine->evaluate("'123'"));
+    DEFINE_TEST_VALUE(engine->evaluate("'12.4'"));
+    DEFINE_TEST_VALUE(engine->nullValue());
+    DEFINE_TEST_VALUE(engine->undefinedValue());
+}
+
+
+void tst_QScriptValue::isValid_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isValid_makeData(const char* expr)
+{
+    static QSet<QString> isValid;
+    if (isValid.isEmpty()) {
+        isValid << "QScriptValue(QScriptValue::UndefinedValue)"
+                << "QScriptValue(QScriptValue::NullValue)"
+                << "QScriptValue(true)"
+                << "QScriptValue(false)"
+                << "QScriptValue(int(122))"
+                << "QScriptValue(uint(124))"
+                << "QScriptValue(0)"
+                << "QScriptValue(0.0)"
+                << "QScriptValue(123.0)"
+                << "QScriptValue(6.37e-8)"
+                << "QScriptValue(-6.37e-8)"
+                << "QScriptValue(0x43211234)"
+                << "QScriptValue(0x10000)"
+                << "QScriptValue(0x10001)"
+                << "QScriptValue(qSNaN())"
+                << "QScriptValue(qQNaN())"
+                << "QScriptValue(qInf())"
+                << "QScriptValue(-qInf())"
+                << "QScriptValue(\"NaN\")"
+                << "QScriptValue(\"Infinity\")"
+                << "QScriptValue(\"-Infinity\")"
+                << "QScriptValue(\"ciao\")"
+                << "QScriptValue(QString::fromLatin1(\"ciao\"))"
+                << "QScriptValue(QString(\"\"))"
+                << "QScriptValue(QString())"
+                << "QScriptValue(QString(\"0\"))"
+                << "QScriptValue(QString(\"123\"))"
+                << "QScriptValue(QString(\"12.4\"))"
+                << "QScriptValue(0, QScriptValue::UndefinedValue)"
+                << "QScriptValue(0, QScriptValue::NullValue)"
+                << "QScriptValue(0, true)"
+                << "QScriptValue(0, false)"
+                << "QScriptValue(0, int(122))"
+                << "QScriptValue(0, uint(124))"
+                << "QScriptValue(0, 0)"
+                << "QScriptValue(0, 0.0)"
+                << "QScriptValue(0, 123.0)"
+                << "QScriptValue(0, 6.37e-8)"
+                << "QScriptValue(0, -6.37e-8)"
+                << "QScriptValue(0, 0x43211234)"
+                << "QScriptValue(0, 0x10000)"
+                << "QScriptValue(0, 0x10001)"
+                << "QScriptValue(0, qSNaN())"
+                << "QScriptValue(0, qQNaN())"
+                << "QScriptValue(0, qInf())"
+                << "QScriptValue(0, -qInf())"
+                << "QScriptValue(0, \"NaN\")"
+                << "QScriptValue(0, \"Infinity\")"
+                << "QScriptValue(0, \"-Infinity\")"
+                << "QScriptValue(0, \"ciao\")"
+                << "QScriptValue(0, QString::fromLatin1(\"ciao\"))"
+                << "QScriptValue(0, QString(\"\"))"
+                << "QScriptValue(0, QString())"
+                << "QScriptValue(0, QString(\"0\"))"
+                << "QScriptValue(0, QString(\"123\"))"
+                << "QScriptValue(0, QString(\"12.3\"))"
+                << "QScriptValue(engine, QScriptValue::UndefinedValue)"
+                << "QScriptValue(engine, QScriptValue::NullValue)"
+                << "QScriptValue(engine, true)"
+                << "QScriptValue(engine, false)"
+                << "QScriptValue(engine, int(122))"
+                << "QScriptValue(engine, uint(124))"
+                << "QScriptValue(engine, 0)"
+                << "QScriptValue(engine, 0.0)"
+                << "QScriptValue(engine, 123.0)"
+                << "QScriptValue(engine, 6.37e-8)"
+                << "QScriptValue(engine, -6.37e-8)"
+                << "QScriptValue(engine, 0x43211234)"
+                << "QScriptValue(engine, 0x10000)"
+                << "QScriptValue(engine, 0x10001)"
+                << "QScriptValue(engine, qSNaN())"
+                << "QScriptValue(engine, qQNaN())"
+                << "QScriptValue(engine, qInf())"
+                << "QScriptValue(engine, -qInf())"
+                << "QScriptValue(engine, \"NaN\")"
+                << "QScriptValue(engine, \"Infinity\")"
+                << "QScriptValue(engine, \"-Infinity\")"
+                << "QScriptValue(engine, \"ciao\")"
+                << "QScriptValue(engine, QString::fromLatin1(\"ciao\"))"
+                << "QScriptValue(engine, QString(\"\"))"
+                << "QScriptValue(engine, QString())"
+                << "QScriptValue(engine, QString(\"0\"))"
+                << "QScriptValue(engine, QString(\"123\"))"
+                << "QScriptValue(engine, QString(\"1.23\"))"
+                << "engine->evaluate(\"[]\")"
+                << "engine->evaluate(\"{}\")"
+                << "engine->evaluate(\"Object.prototype\")"
+                << "engine->evaluate(\"Date.prototype\")"
+                << "engine->evaluate(\"Array.prototype\")"
+                << "engine->evaluate(\"Function.prototype\")"
+                << "engine->evaluate(\"Error.prototype\")"
+                << "engine->evaluate(\"Object\")"
+                << "engine->evaluate(\"Array\")"
+                << "engine->evaluate(\"Number\")"
+                << "engine->evaluate(\"Function\")"
+                << "engine->evaluate(\"(function() { return 1; })\")"
+                << "engine->evaluate(\"(function() { return 'ciao'; })\")"
+                << "engine->evaluate(\"(function() { throw new Error('foo'); })\")"
+                << "engine->evaluate(\"/foo/\")"
+                << "engine->evaluate(\"new Object()\")"
+                << "engine->evaluate(\"new Array()\")"
+                << "engine->evaluate(\"new Error()\")"
+                << "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")"
+                << "engine->evaluate(\"Undefined\")"
+                << "engine->evaluate(\"Null\")"
+                << "engine->evaluate(\"True\")"
+                << "engine->evaluate(\"False\")"
+                << "engine->evaluate(\"undefined\")"
+                << "engine->evaluate(\"null\")"
+                << "engine->evaluate(\"true\")"
+                << "engine->evaluate(\"false\")"
+                << "engine->evaluate(\"122\")"
+                << "engine->evaluate(\"124\")"
+                << "engine->evaluate(\"0\")"
+                << "engine->evaluate(\"0.0\")"
+                << "engine->evaluate(\"123.0\")"
+                << "engine->evaluate(\"6.37e-8\")"
+                << "engine->evaluate(\"-6.37e-8\")"
+                << "engine->evaluate(\"0x43211234\")"
+                << "engine->evaluate(\"0x10000\")"
+                << "engine->evaluate(\"0x10001\")"
+                << "engine->evaluate(\"NaN\")"
+                << "engine->evaluate(\"Infinity\")"
+                << "engine->evaluate(\"-Infinity\")"
+                << "engine->evaluate(\"'ciao'\")"
+                << "engine->evaluate(\"''\")"
+                << "engine->evaluate(\"'0'\")"
+                << "engine->evaluate(\"'123'\")"
+                << "engine->evaluate(\"'12.4'\")"
+                << "engine->nullValue()"
+                << "engine->undefinedValue()";
+    }
+    newRow(expr) << isValid.contains(expr);
+}
+
+void tst_QScriptValue::isValid_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isValid(), expected);
+    QCOMPARE(value.isValid(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isValid)
+
+
+void tst_QScriptValue::isBool_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isBool_makeData(const char* expr)
+{
+    static QSet<QString> isBool;
+    if (isBool.isEmpty()) {
+        isBool << "QScriptValue(true)"
+                << "QScriptValue(false)"
+                << "QScriptValue(0, true)"
+                << "QScriptValue(0, false)"
+                << "QScriptValue(engine, true)"
+                << "QScriptValue(engine, false)"
+                << "engine->evaluate(\"true\")"
+                << "engine->evaluate(\"false\")";
+    }
+    newRow(expr) << isBool.contains(expr);
+}
+
+void tst_QScriptValue::isBool_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isBool(), expected);
+    QCOMPARE(value.isBool(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isBool)
+
+
+void tst_QScriptValue::isBoolean_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isBoolean_makeData(const char* expr)
+{
+    static QSet<QString> isBoolean;
+    if (isBoolean.isEmpty()) {
+        isBoolean << "QScriptValue(true)"
+                << "QScriptValue(false)"
+                << "QScriptValue(0, true)"
+                << "QScriptValue(0, false)"
+                << "QScriptValue(engine, true)"
+                << "QScriptValue(engine, false)"
+                << "engine->evaluate(\"true\")"
+                << "engine->evaluate(\"false\")";
+    }
+    newRow(expr) << isBoolean.contains(expr);
+}
+
+void tst_QScriptValue::isBoolean_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isBoolean(), expected);
+    QCOMPARE(value.isBoolean(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isBoolean)
+
+
+void tst_QScriptValue::isNumber_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isNumber_makeData(const char* expr)
+{
+    static QSet<QString> isNumber;
+    if (isNumber.isEmpty()) {
+        isNumber << "QScriptValue(int(122))"
+                << "QScriptValue(uint(124))"
+                << "QScriptValue(0)"
+                << "QScriptValue(0.0)"
+                << "QScriptValue(123.0)"
+                << "QScriptValue(6.37e-8)"
+                << "QScriptValue(-6.37e-8)"
+                << "QScriptValue(0x43211234)"
+                << "QScriptValue(0x10000)"
+                << "QScriptValue(0x10001)"
+                << "QScriptValue(qSNaN())"
+                << "QScriptValue(qQNaN())"
+                << "QScriptValue(qInf())"
+                << "QScriptValue(-qInf())"
+                << "QScriptValue(0, int(122))"
+                << "QScriptValue(0, uint(124))"
+                << "QScriptValue(0, 0)"
+                << "QScriptValue(0, 0.0)"
+                << "QScriptValue(0, 123.0)"
+                << "QScriptValue(0, 6.37e-8)"
+                << "QScriptValue(0, -6.37e-8)"
+                << "QScriptValue(0, 0x43211234)"
+                << "QScriptValue(0, 0x10000)"
+                << "QScriptValue(0, 0x10001)"
+                << "QScriptValue(0, qSNaN())"
+                << "QScriptValue(0, qQNaN())"
+                << "QScriptValue(0, qInf())"
+                << "QScriptValue(0, -qInf())"
+                << "QScriptValue(engine, int(122))"
+                << "QScriptValue(engine, uint(124))"
+                << "QScriptValue(engine, 0)"
+                << "QScriptValue(engine, 0.0)"
+                << "QScriptValue(engine, 123.0)"
+                << "QScriptValue(engine, 6.37e-8)"
+                << "QScriptValue(engine, -6.37e-8)"
+                << "QScriptValue(engine, 0x43211234)"
+                << "QScriptValue(engine, 0x10000)"
+                << "QScriptValue(engine, 0x10001)"
+                << "QScriptValue(engine, qSNaN())"
+                << "QScriptValue(engine, qQNaN())"
+                << "QScriptValue(engine, qInf())"
+                << "QScriptValue(engine, -qInf())"
+                << "engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")"
+                << "engine->evaluate(\"122\")"
+                << "engine->evaluate(\"124\")"
+                << "engine->evaluate(\"0\")"
+                << "engine->evaluate(\"0.0\")"
+                << "engine->evaluate(\"123.0\")"
+                << "engine->evaluate(\"6.37e-8\")"
+                << "engine->evaluate(\"-6.37e-8\")"
+                << "engine->evaluate(\"0x43211234\")"
+                << "engine->evaluate(\"0x10000\")"
+                << "engine->evaluate(\"0x10001\")"
+                << "engine->evaluate(\"NaN\")"
+                << "engine->evaluate(\"Infinity\")"
+                << "engine->evaluate(\"-Infinity\")";
+    }
+    newRow(expr) << isNumber.contains(expr);
+}
+
+void tst_QScriptValue::isNumber_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isNumber(), expected);
+    QCOMPARE(value.isNumber(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isNumber)
+
+
+void tst_QScriptValue::isFunction_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isFunction_makeData(const char* expr)
+{
+    static QSet<QString> isFunction;
+    if (isFunction.isEmpty()) {
+        isFunction << "engine->evaluate(\"Function.prototype\")"
+                << "engine->evaluate(\"Object\")"
+                << "engine->evaluate(\"Array\")"
+                << "engine->evaluate(\"Number\")"
+                << "engine->evaluate(\"Function\")"
+                << "engine->evaluate(\"(function() { return 1; })\")"
+                << "engine->evaluate(\"(function() { return 'ciao'; })\")"
+                << "engine->evaluate(\"(function() { throw new Error('foo'); })\")"
+                << "engine->evaluate(\"/foo/\")";
+    }
+    newRow(expr) << isFunction.contains(expr);
+}
+
+void tst_QScriptValue::isFunction_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isFunction(), expected);
+    QCOMPARE(value.isFunction(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isFunction)
+
+
+void tst_QScriptValue::isNull_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isNull_makeData(const char* expr)
+{
+    static QSet<QString> isNull;
+    if (isNull.isEmpty()) {
+        isNull << "QScriptValue(QScriptValue::NullValue)"
+                << "QScriptValue(0, QScriptValue::NullValue)"
+                << "QScriptValue(engine, QScriptValue::NullValue)"
+                << "engine->evaluate(\"null\")"
+                << "engine->nullValue()";
+    }
+    newRow(expr) << isNull.contains(expr);
+}
+
+void tst_QScriptValue::isNull_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isNull(), expected);
+    QCOMPARE(value.isNull(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isNull)
+
+
+void tst_QScriptValue::isString_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isString_makeData(const char* expr)
+{
+    static QSet<QString> isString;
+    if (isString.isEmpty()) {
+        isString << "QScriptValue(\"NaN\")"
+                << "QScriptValue(\"Infinity\")"
+                << "QScriptValue(\"-Infinity\")"
+                << "QScriptValue(\"ciao\")"
+                << "QScriptValue(QString::fromLatin1(\"ciao\"))"
+                << "QScriptValue(QString(\"\"))"
+                << "QScriptValue(QString())"
+                << "QScriptValue(QString(\"0\"))"
+                << "QScriptValue(QString(\"123\"))"
+                << "QScriptValue(QString(\"12.4\"))"
+                << "QScriptValue(0, \"NaN\")"
+                << "QScriptValue(0, \"Infinity\")"
+                << "QScriptValue(0, \"-Infinity\")"
+                << "QScriptValue(0, \"ciao\")"
+                << "QScriptValue(0, QString::fromLatin1(\"ciao\"))"
+                << "QScriptValue(0, QString(\"\"))"
+                << "QScriptValue(0, QString())"
+                << "QScriptValue(0, QString(\"0\"))"
+                << "QScriptValue(0, QString(\"123\"))"
+                << "QScriptValue(0, QString(\"12.3\"))"
+                << "QScriptValue(engine, \"NaN\")"
+                << "QScriptValue(engine, \"Infinity\")"
+                << "QScriptValue(engine, \"-Infinity\")"
+                << "QScriptValue(engine, \"ciao\")"
+                << "QScriptValue(engine, QString::fromLatin1(\"ciao\"))"
+                << "QScriptValue(engine, QString(\"\"))"
+                << "QScriptValue(engine, QString())"
+                << "QScriptValue(engine, QString(\"0\"))"
+                << "QScriptValue(engine, QString(\"123\"))"
+                << "QScriptValue(engine, QString(\"1.23\"))"
+                << "engine->evaluate(\"'ciao'\")"
+                << "engine->evaluate(\"''\")"
+                << "engine->evaluate(\"'0'\")"
+                << "engine->evaluate(\"'123'\")"
+                << "engine->evaluate(\"'12.4'\")";
+    }
+    newRow(expr) << isString.contains(expr);
+}
+
+void tst_QScriptValue::isString_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isString(), expected);
+    QCOMPARE(value.isString(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isString)
+
+
+void tst_QScriptValue::isUndefined_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isUndefined_makeData(const char* expr)
+{
+    static QSet<QString> isUndefined;
+    if (isUndefined.isEmpty()) {
+        isUndefined << "QScriptValue(QScriptValue::UndefinedValue)"
+                << "QScriptValue(0, QScriptValue::UndefinedValue)"
+                << "QScriptValue(engine, QScriptValue::UndefinedValue)"
+                << "engine->evaluate(\"{}\")"
+                << "engine->evaluate(\"undefined\")"
+                << "engine->undefinedValue()";
+    }
+    newRow(expr) << isUndefined.contains(expr);
+}
+
+void tst_QScriptValue::isUndefined_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isUndefined(), expected);
+    QCOMPARE(value.isUndefined(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isUndefined)
+
+
+
+
+
+void tst_QScriptValue::isObject_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::isObject_makeData(const char* expr)
+{
+    static QSet<QString> isObject;
+    if (isObject.isEmpty()) {
+        isObject << "engine->evaluate(\"[]\")"
+                << "engine->evaluate(\"Object.prototype\")"
+                << "engine->evaluate(\"Date.prototype\")"
+                << "engine->evaluate(\"Array.prototype\")"
+                << "engine->evaluate(\"Function.prototype\")"
+                << "engine->evaluate(\"Error.prototype\")"
+                << "engine->evaluate(\"Object\")"
+                << "engine->evaluate(\"Array\")"
+                << "engine->evaluate(\"Number\")"
+                << "engine->evaluate(\"Function\")"
+                << "engine->evaluate(\"(function() { return 1; })\")"
+                << "engine->evaluate(\"(function() { return 'ciao'; })\")"
+                << "engine->evaluate(\"(function() { throw new Error('foo'); })\")"
+                << "engine->evaluate(\"/foo/\")"
+                << "engine->evaluate(\"new Object()\")"
+                << "engine->evaluate(\"new Array()\")"
+                << "engine->evaluate(\"new Error()\")"
+                << "engine->evaluate(\"Undefined\")"
+                << "engine->evaluate(\"Null\")"
+                << "engine->evaluate(\"True\")"
+                << "engine->evaluate(\"False\")";
+    }
+    newRow(expr) << isObject.contains(expr);
+}
+
+void tst_QScriptValue::isObject_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.isObject(), expected);
+    QCOMPARE(value.isObject(), expected);
+}
+
+DEFINE_TEST_FUNCTION(isObject)
+
+
+void tst_QScriptValue::toString_initData()
+{
+    QTest::addColumn<QString>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::toString_makeData(const char* expr)
+{
+    static QHash<QString, QString> toString;
+    if (toString.isEmpty()) {
+        toString.insert("QScriptValue()", "");
+        toString.insert("QScriptValue(QScriptValue::UndefinedValue)", "undefined");
+        toString.insert("QScriptValue(QScriptValue::NullValue)", "null");
+        toString.insert("QScriptValue(true)", "true");
+        toString.insert("QScriptValue(false)", "false");
+        toString.insert("QScriptValue(int(122))", "122");
+        toString.insert("QScriptValue(uint(124))", "124");
+        toString.insert("QScriptValue(0)", "0");
+        toString.insert("QScriptValue(0.0)", "0");
+        toString.insert("QScriptValue(123.0)", "123");
+        toString.insert("QScriptValue(6.37e-8)", "6.37e-8");
+        toString.insert("QScriptValue(-6.37e-8)", "-6.37e-8");
+        toString.insert("QScriptValue(0x43211234)", "1126240820");
+        toString.insert("QScriptValue(0x10000)", "65536");
+        toString.insert("QScriptValue(0x10001)", "65537");
+        toString.insert("QScriptValue(qSNaN())", "NaN");
+        toString.insert("QScriptValue(qQNaN())", "NaN");
+        toString.insert("QScriptValue(qInf())", "Infinity");
+        toString.insert("QScriptValue(-qInf())", "-Infinity");
+        toString.insert("QScriptValue(\"NaN\")", "NaN");
+        toString.insert("QScriptValue(\"Infinity\")", "Infinity");
+        toString.insert("QScriptValue(\"-Infinity\")", "-Infinity");
+        toString.insert("QScriptValue(\"ciao\")", "ciao");
+        toString.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", "ciao");
+        toString.insert("QScriptValue(QString(\"\"))", "");
+        toString.insert("QScriptValue(QString())", "");
+        toString.insert("QScriptValue(QString(\"0\"))", "0");
+        toString.insert("QScriptValue(QString(\"123\"))", "123");
+        toString.insert("QScriptValue(QString(\"12.4\"))", "12.4");
+        toString.insert("QScriptValue(0, QScriptValue::UndefinedValue)", "undefined");
+        toString.insert("QScriptValue(0, QScriptValue::NullValue)", "null");
+        toString.insert("QScriptValue(0, true)", "true");
+        toString.insert("QScriptValue(0, false)", "false");
+        toString.insert("QScriptValue(0, int(122))", "122");
+        toString.insert("QScriptValue(0, uint(124))", "124");
+        toString.insert("QScriptValue(0, 0)", "0");
+        toString.insert("QScriptValue(0, 0.0)", "0");
+        toString.insert("QScriptValue(0, 123.0)", "123");
+        toString.insert("QScriptValue(0, 6.37e-8)", "6.37e-8");
+        toString.insert("QScriptValue(0, -6.37e-8)", "-6.37e-8");
+        toString.insert("QScriptValue(0, 0x43211234)", "1126240820");
+        toString.insert("QScriptValue(0, 0x10000)", "65536");
+        toString.insert("QScriptValue(0, 0x10001)", "65537");
+        toString.insert("QScriptValue(0, qSNaN())", "NaN");
+        toString.insert("QScriptValue(0, qQNaN())", "NaN");
+        toString.insert("QScriptValue(0, qInf())", "Infinity");
+        toString.insert("QScriptValue(0, -qInf())", "-Infinity");
+        toString.insert("QScriptValue(0, \"NaN\")", "NaN");
+        toString.insert("QScriptValue(0, \"Infinity\")", "Infinity");
+        toString.insert("QScriptValue(0, \"-Infinity\")", "-Infinity");
+        toString.insert("QScriptValue(0, \"ciao\")", "ciao");
+        toString.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", "ciao");
+        toString.insert("QScriptValue(0, QString(\"\"))", "");
+        toString.insert("QScriptValue(0, QString())", "");
+        toString.insert("QScriptValue(0, QString(\"0\"))", "0");
+        toString.insert("QScriptValue(0, QString(\"123\"))", "123");
+        toString.insert("QScriptValue(0, QString(\"12.3\"))", "12.3");
+        toString.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", "undefined");
+        toString.insert("QScriptValue(engine, QScriptValue::NullValue)", "null");
+        toString.insert("QScriptValue(engine, true)", "true");
+        toString.insert("QScriptValue(engine, false)", "false");
+        toString.insert("QScriptValue(engine, int(122))", "122");
+        toString.insert("QScriptValue(engine, uint(124))", "124");
+        toString.insert("QScriptValue(engine, 0)", "0");
+        toString.insert("QScriptValue(engine, 0.0)", "0");
+        toString.insert("QScriptValue(engine, 123.0)", "123");
+        toString.insert("QScriptValue(engine, 6.37e-8)", "6.37e-8");
+        toString.insert("QScriptValue(engine, -6.37e-8)", "-6.37e-8");
+        toString.insert("QScriptValue(engine, 0x43211234)", "1126240820");
+        toString.insert("QScriptValue(engine, 0x10000)", "65536");
+        toString.insert("QScriptValue(engine, 0x10001)", "65537");
+        toString.insert("QScriptValue(engine, qSNaN())", "NaN");
+        toString.insert("QScriptValue(engine, qQNaN())", "NaN");
+        toString.insert("QScriptValue(engine, qInf())", "Infinity");
+        toString.insert("QScriptValue(engine, -qInf())", "-Infinity");
+        toString.insert("QScriptValue(engine, \"NaN\")", "NaN");
+        toString.insert("QScriptValue(engine, \"Infinity\")", "Infinity");
+        toString.insert("QScriptValue(engine, \"-Infinity\")", "-Infinity");
+        toString.insert("QScriptValue(engine, \"ciao\")", "ciao");
+        toString.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", "ciao");
+        toString.insert("QScriptValue(engine, QString(\"\"))", "");
+        toString.insert("QScriptValue(engine, QString())", "");
+        toString.insert("QScriptValue(engine, QString(\"0\"))", "0");
+        toString.insert("QScriptValue(engine, QString(\"123\"))", "123");
+        toString.insert("QScriptValue(engine, QString(\"1.23\"))", "1.23");
+        toString.insert("engine->evaluate(\"[]\")", "");
+        toString.insert("engine->evaluate(\"{}\")", "undefined");
+        toString.insert("engine->evaluate(\"Object.prototype\")", "[object Object]");
+        toString.insert("engine->evaluate(\"Date.prototype\")", "Invalid Date");
+        toString.insert("engine->evaluate(\"Array.prototype\")", "");
+        toString.insert("engine->evaluate(\"Function.prototype\")", "function () {\n    [native code]\n}");
+        toString.insert("engine->evaluate(\"Error.prototype\")", "Error: Unknown error");
+        toString.insert("engine->evaluate(\"Object\")", "function Object() {\n    [native code]\n}");
+        toString.insert("engine->evaluate(\"Array\")", "function Array() {\n    [native code]\n}");
+        toString.insert("engine->evaluate(\"Number\")", "function Number() {\n    [native code]\n}");
+        toString.insert("engine->evaluate(\"Function\")", "function Function() {\n    [native code]\n}");
+        toString.insert("engine->evaluate(\"(function() { return 1; })\")", "function () { return 1; }");
+        toString.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", "function () { return 'ciao'; }");
+        toString.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", "function () { throw new Error('foo'); }");
+        toString.insert("engine->evaluate(\"/foo/\")", "/foo/");
+        toString.insert("engine->evaluate(\"new Object()\")", "[object Object]");
+        toString.insert("engine->evaluate(\"new Array()\")", "");
+        toString.insert("engine->evaluate(\"new Error()\")", "Error: Unknown error");
+        toString.insert("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", "22");
+        toString.insert("engine->evaluate(\"Undefined\")", "ReferenceError: Can't find variable: Undefined");
+        toString.insert("engine->evaluate(\"Null\")", "ReferenceError: Can't find variable: Null");
+        toString.insert("engine->evaluate(\"True\")", "ReferenceError: Can't find variable: True");
+        toString.insert("engine->evaluate(\"False\")", "ReferenceError: Can't find variable: False");
+        toString.insert("engine->evaluate(\"undefined\")", "undefined");
+        toString.insert("engine->evaluate(\"null\")", "null");
+        toString.insert("engine->evaluate(\"true\")", "true");
+        toString.insert("engine->evaluate(\"false\")", "false");
+        toString.insert("engine->evaluate(\"122\")", "122");
+        toString.insert("engine->evaluate(\"124\")", "124");
+        toString.insert("engine->evaluate(\"0\")", "0");
+        toString.insert("engine->evaluate(\"0.0\")", "0");
+        toString.insert("engine->evaluate(\"123.0\")", "123");
+        toString.insert("engine->evaluate(\"6.37e-8\")", "6.37e-8");
+        toString.insert("engine->evaluate(\"-6.37e-8\")", "-6.37e-8");
+        toString.insert("engine->evaluate(\"0x43211234\")", "1126240820");
+        toString.insert("engine->evaluate(\"0x10000\")", "65536");
+        toString.insert("engine->evaluate(\"0x10001\")", "65537");
+        toString.insert("engine->evaluate(\"NaN\")", "NaN");
+        toString.insert("engine->evaluate(\"Infinity\")", "Infinity");
+        toString.insert("engine->evaluate(\"-Infinity\")", "-Infinity");
+        toString.insert("engine->evaluate(\"'ciao'\")", "ciao");
+        toString.insert("engine->evaluate(\"''\")", "");
+        toString.insert("engine->evaluate(\"'0'\")", "0");
+        toString.insert("engine->evaluate(\"'123'\")", "123");
+        toString.insert("engine->evaluate(\"'12.4'\")", "12.4");
+        toString.insert("engine->nullValue()", "null");
+        toString.insert("engine->undefinedValue()", "undefined");
+    }
+    newRow(expr) << toString.value(expr);
+}
+
+void tst_QScriptValue::toString_test(const char*, const QScriptValue& value)
+{
+    QFETCH(QString, expected);
+    QCOMPARE(value.toString(), expected);
+    QCOMPARE(value.toString(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toString)
+
+
+void tst_QScriptValue::toNumber_initData()
+{
+    QTest::addColumn<qsreal>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::toNumber_makeData(const char* expr)
+{
+    static QHash<QString, qsreal> toNumber;
+    if (toNumber.isEmpty()) {
+        toNumber.insert("QScriptValue()", 0);
+        toNumber.insert("QScriptValue(QScriptValue::UndefinedValue)", qQNaN());
+        toNumber.insert("QScriptValue(QScriptValue::NullValue)", 0);
+        toNumber.insert("QScriptValue(true)", 1);
+        toNumber.insert("QScriptValue(false)", 0);
+        toNumber.insert("QScriptValue(int(122))", 122);
+        toNumber.insert("QScriptValue(uint(124))", 124);
+        toNumber.insert("QScriptValue(0)", 0);
+        toNumber.insert("QScriptValue(0.0)", 0);
+        toNumber.insert("QScriptValue(123.0)", 123);
+        toNumber.insert("QScriptValue(6.37e-8)", 6.369999999999999e-08);
+        toNumber.insert("QScriptValue(-6.37e-8)", -6.369999999999999e-08);
+        toNumber.insert("QScriptValue(0x43211234)", 1126240820);
+        toNumber.insert("QScriptValue(0x10000)", 65536);
+        toNumber.insert("QScriptValue(0x10001)", 65537);
+        toNumber.insert("QScriptValue(qSNaN())", qQNaN());
+        toNumber.insert("QScriptValue(qQNaN())", qQNaN());
+        toNumber.insert("QScriptValue(qInf())", qInf());
+        toNumber.insert("QScriptValue(-qInf())", qInf());
+        toNumber.insert("QScriptValue(\"NaN\")", qQNaN());
+        toNumber.insert("QScriptValue(\"Infinity\")", qInf());
+        toNumber.insert("QScriptValue(\"-Infinity\")", qInf());
+        toNumber.insert("QScriptValue(\"ciao\")", qQNaN());
+        toNumber.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", qQNaN());
+        toNumber.insert("QScriptValue(QString(\"\"))", 0);
+        toNumber.insert("QScriptValue(QString())", 0);
+        toNumber.insert("QScriptValue(QString(\"0\"))", 0);
+        toNumber.insert("QScriptValue(QString(\"123\"))", 123);
+        toNumber.insert("QScriptValue(QString(\"12.4\"))", 12.4);
+        toNumber.insert("QScriptValue(0, QScriptValue::UndefinedValue)", qQNaN());
+        toNumber.insert("QScriptValue(0, QScriptValue::NullValue)", 0);
+        toNumber.insert("QScriptValue(0, true)", 1);
+        toNumber.insert("QScriptValue(0, false)", 0);
+        toNumber.insert("QScriptValue(0, int(122))", 122);
+        toNumber.insert("QScriptValue(0, uint(124))", 124);
+        toNumber.insert("QScriptValue(0, 0)", 0);
+        toNumber.insert("QScriptValue(0, 0.0)", 0);
+        toNumber.insert("QScriptValue(0, 123.0)", 123);
+        toNumber.insert("QScriptValue(0, 6.37e-8)", 6.369999999999999e-08);
+        toNumber.insert("QScriptValue(0, -6.37e-8)", -6.369999999999999e-08);
+        toNumber.insert("QScriptValue(0, 0x43211234)", 1126240820);
+        toNumber.insert("QScriptValue(0, 0x10000)", 65536);
+        toNumber.insert("QScriptValue(0, 0x10001)", 65537);
+        toNumber.insert("QScriptValue(0, qSNaN())", qQNaN());
+        toNumber.insert("QScriptValue(0, qQNaN())", qQNaN());
+        toNumber.insert("QScriptValue(0, qInf())", qInf());
+        toNumber.insert("QScriptValue(0, -qInf())", qInf());
+        toNumber.insert("QScriptValue(0, \"NaN\")", qQNaN());
+        toNumber.insert("QScriptValue(0, \"Infinity\")", qInf());
+        toNumber.insert("QScriptValue(0, \"-Infinity\")", qInf());
+        toNumber.insert("QScriptValue(0, \"ciao\")", qQNaN());
+        toNumber.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", qQNaN());
+        toNumber.insert("QScriptValue(0, QString(\"\"))", 0);
+        toNumber.insert("QScriptValue(0, QString())", 0);
+        toNumber.insert("QScriptValue(0, QString(\"0\"))", 0);
+        toNumber.insert("QScriptValue(0, QString(\"123\"))", 123);
+        toNumber.insert("QScriptValue(0, QString(\"12.3\"))", 12.3);
+        toNumber.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", qQNaN());
+        toNumber.insert("QScriptValue(engine, QScriptValue::NullValue)", 0);
+        toNumber.insert("QScriptValue(engine, true)", 1);
+        toNumber.insert("QScriptValue(engine, false)", 0);
+        toNumber.insert("QScriptValue(engine, int(122))", 122);
+        toNumber.insert("QScriptValue(engine, uint(124))", 124);
+        toNumber.insert("QScriptValue(engine, 0)", 0);
+        toNumber.insert("QScriptValue(engine, 0.0)", 0);
+        toNumber.insert("QScriptValue(engine, 123.0)", 123);
+        toNumber.insert("QScriptValue(engine, 6.37e-8)", 6.369999999999999e-08);
+        toNumber.insert("QScriptValue(engine, -6.37e-8)", -6.369999999999999e-08);
+        toNumber.insert("QScriptValue(engine, 0x43211234)", 1126240820);
+        toNumber.insert("QScriptValue(engine, 0x10000)", 65536);
+        toNumber.insert("QScriptValue(engine, 0x10001)", 65537);
+        toNumber.insert("QScriptValue(engine, qSNaN())", qQNaN());
+        toNumber.insert("QScriptValue(engine, qQNaN())", qQNaN());
+        toNumber.insert("QScriptValue(engine, qInf())", qInf());
+        toNumber.insert("QScriptValue(engine, -qInf())", qInf());
+        toNumber.insert("QScriptValue(engine, \"NaN\")", qQNaN());
+        toNumber.insert("QScriptValue(engine, \"Infinity\")", qInf());
+        toNumber.insert("QScriptValue(engine, \"-Infinity\")", qInf());
+        toNumber.insert("QScriptValue(engine, \"ciao\")", qQNaN());
+        toNumber.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", qQNaN());
+        toNumber.insert("QScriptValue(engine, QString(\"\"))", 0);
+        toNumber.insert("QScriptValue(engine, QString())", 0);
+        toNumber.insert("QScriptValue(engine, QString(\"0\"))", 0);
+        toNumber.insert("QScriptValue(engine, QString(\"123\"))", 123);
+        toNumber.insert("QScriptValue(engine, QString(\"1.23\"))", 1.23);
+        toNumber.insert("engine->evaluate(\"[]\")", 0);
+        toNumber.insert("engine->evaluate(\"{}\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Object.prototype\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Date.prototype\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Array.prototype\")", 0);
+        toNumber.insert("engine->evaluate(\"Function.prototype\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Error.prototype\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Object\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Array\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Number\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Function\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"(function() { return 1; })\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"/foo/\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"new Object()\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"new Array()\")", 0);
+        toNumber.insert("engine->evaluate(\"new Error()\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", 22);
+        toNumber.insert("engine->evaluate(\"Undefined\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Null\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"True\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"False\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"undefined\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"null\")", 0);
+        toNumber.insert("engine->evaluate(\"true\")", 1);
+        toNumber.insert("engine->evaluate(\"false\")", 0);
+        toNumber.insert("engine->evaluate(\"122\")", 122);
+        toNumber.insert("engine->evaluate(\"124\")", 124);
+        toNumber.insert("engine->evaluate(\"0\")", 0);
+        toNumber.insert("engine->evaluate(\"0.0\")", 0);
+        toNumber.insert("engine->evaluate(\"123.0\")", 123);
+        toNumber.insert("engine->evaluate(\"6.37e-8\")", 6.369999999999999e-08);
+        toNumber.insert("engine->evaluate(\"-6.37e-8\")", -6.369999999999999e-08);
+        toNumber.insert("engine->evaluate(\"0x43211234\")", 1126240820);
+        toNumber.insert("engine->evaluate(\"0x10000\")", 65536);
+        toNumber.insert("engine->evaluate(\"0x10001\")", 65537);
+        toNumber.insert("engine->evaluate(\"NaN\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"Infinity\")", qInf());
+        toNumber.insert("engine->evaluate(\"-Infinity\")", qInf());
+        toNumber.insert("engine->evaluate(\"'ciao'\")", qQNaN());
+        toNumber.insert("engine->evaluate(\"''\")", 0);
+        toNumber.insert("engine->evaluate(\"'0'\")", 0);
+        toNumber.insert("engine->evaluate(\"'123'\")", 123);
+        toNumber.insert("engine->evaluate(\"'12.4'\")", 12.4);
+        toNumber.insert("engine->nullValue()", 0);
+        toNumber.insert("engine->undefinedValue()", qQNaN());
+    }
+    newRow(expr) << toNumber.value(expr);
+}
+
+void tst_QScriptValue::toNumber_test(const char*, const QScriptValue& value)
+{
+    QFETCH(qsreal, expected);
+    if (qIsNaN(expected)) {
+        QVERIFY(qIsNaN(value.toNumber()));
+        return;
+    }
+    if (qIsInf(expected)) {
+        QVERIFY(qIsInf(value.toNumber()));
+        QVERIFY(qIsInf(value.toNumber()));
+        return;
+    }
+    QCOMPARE(value.toNumber(), expected);
+    QCOMPARE(value.toNumber(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toNumber)
+
+
+void tst_QScriptValue::toBool_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::toBool_makeData(const char* expr)
+{
+    static QHash<QString, bool> toBool;
+    if (toBool.isEmpty()) {
+        toBool.insert("QScriptValue()", false);
+        toBool.insert("QScriptValue(QScriptValue::UndefinedValue)", false);
+        toBool.insert("QScriptValue(QScriptValue::NullValue)", false);
+        toBool.insert("QScriptValue(true)", true);
+        toBool.insert("QScriptValue(false)", false);
+        toBool.insert("QScriptValue(int(122))", true);
+        toBool.insert("QScriptValue(uint(124))", true);
+        toBool.insert("QScriptValue(0)", false);
+        toBool.insert("QScriptValue(0.0)", false);
+        toBool.insert("QScriptValue(123.0)", true);
+        toBool.insert("QScriptValue(6.37e-8)", true);
+        toBool.insert("QScriptValue(-6.37e-8)", true);
+        toBool.insert("QScriptValue(0x43211234)", true);
+        toBool.insert("QScriptValue(0x10000)", true);
+        toBool.insert("QScriptValue(0x10001)", true);
+        toBool.insert("QScriptValue(qSNaN())", false);
+        toBool.insert("QScriptValue(qQNaN())", false);
+        toBool.insert("QScriptValue(qInf())", true);
+        toBool.insert("QScriptValue(-qInf())", true);
+        toBool.insert("QScriptValue(\"NaN\")", true);
+        toBool.insert("QScriptValue(\"Infinity\")", true);
+        toBool.insert("QScriptValue(\"-Infinity\")", true);
+        toBool.insert("QScriptValue(\"ciao\")", true);
+        toBool.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", true);
+        toBool.insert("QScriptValue(QString(\"\"))", false);
+        toBool.insert("QScriptValue(QString())", false);
+        toBool.insert("QScriptValue(QString(\"0\"))", true);
+        toBool.insert("QScriptValue(QString(\"123\"))", true);
+        toBool.insert("QScriptValue(QString(\"12.4\"))", true);
+        toBool.insert("QScriptValue(0, QScriptValue::UndefinedValue)", false);
+        toBool.insert("QScriptValue(0, QScriptValue::NullValue)", false);
+        toBool.insert("QScriptValue(0, true)", true);
+        toBool.insert("QScriptValue(0, false)", false);
+        toBool.insert("QScriptValue(0, int(122))", true);
+        toBool.insert("QScriptValue(0, uint(124))", true);
+        toBool.insert("QScriptValue(0, 0)", false);
+        toBool.insert("QScriptValue(0, 0.0)", false);
+        toBool.insert("QScriptValue(0, 123.0)", true);
+        toBool.insert("QScriptValue(0, 6.37e-8)", true);
+        toBool.insert("QScriptValue(0, -6.37e-8)", true);
+        toBool.insert("QScriptValue(0, 0x43211234)", true);
+        toBool.insert("QScriptValue(0, 0x10000)", true);
+        toBool.insert("QScriptValue(0, 0x10001)", true);
+        toBool.insert("QScriptValue(0, qSNaN())", false);
+        toBool.insert("QScriptValue(0, qQNaN())", false);
+        toBool.insert("QScriptValue(0, qInf())", true);
+        toBool.insert("QScriptValue(0, -qInf())", true);
+        toBool.insert("QScriptValue(0, \"NaN\")", true);
+        toBool.insert("QScriptValue(0, \"Infinity\")", true);
+        toBool.insert("QScriptValue(0, \"-Infinity\")", true);
+        toBool.insert("QScriptValue(0, \"ciao\")", true);
+        toBool.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", true);
+        toBool.insert("QScriptValue(0, QString(\"\"))", false);
+        toBool.insert("QScriptValue(0, QString())", false);
+        toBool.insert("QScriptValue(0, QString(\"0\"))", true);
+        toBool.insert("QScriptValue(0, QString(\"123\"))", true);
+        toBool.insert("QScriptValue(0, QString(\"12.3\"))", true);
+        toBool.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", false);
+        toBool.insert("QScriptValue(engine, QScriptValue::NullValue)", false);
+        toBool.insert("QScriptValue(engine, true)", true);
+        toBool.insert("QScriptValue(engine, false)", false);
+        toBool.insert("QScriptValue(engine, int(122))", true);
+        toBool.insert("QScriptValue(engine, uint(124))", true);
+        toBool.insert("QScriptValue(engine, 0)", false);
+        toBool.insert("QScriptValue(engine, 0.0)", false);
+        toBool.insert("QScriptValue(engine, 123.0)", true);
+        toBool.insert("QScriptValue(engine, 6.37e-8)", true);
+        toBool.insert("QScriptValue(engine, -6.37e-8)", true);
+        toBool.insert("QScriptValue(engine, 0x43211234)", true);
+        toBool.insert("QScriptValue(engine, 0x10000)", true);
+        toBool.insert("QScriptValue(engine, 0x10001)", true);
+        toBool.insert("QScriptValue(engine, qSNaN())", false);
+        toBool.insert("QScriptValue(engine, qQNaN())", false);
+        toBool.insert("QScriptValue(engine, qInf())", true);
+        toBool.insert("QScriptValue(engine, -qInf())", true);
+        toBool.insert("QScriptValue(engine, \"NaN\")", true);
+        toBool.insert("QScriptValue(engine, \"Infinity\")", true);
+        toBool.insert("QScriptValue(engine, \"-Infinity\")", true);
+        toBool.insert("QScriptValue(engine, \"ciao\")", true);
+        toBool.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", true);
+        toBool.insert("QScriptValue(engine, QString(\"\"))", false);
+        toBool.insert("QScriptValue(engine, QString())", false);
+        toBool.insert("QScriptValue(engine, QString(\"0\"))", true);
+        toBool.insert("QScriptValue(engine, QString(\"123\"))", true);
+        toBool.insert("QScriptValue(engine, QString(\"1.23\"))", true);
+        toBool.insert("engine->evaluate(\"[]\")", true);
+        toBool.insert("engine->evaluate(\"{}\")", false);
+        toBool.insert("engine->evaluate(\"Object.prototype\")", true);
+        toBool.insert("engine->evaluate(\"Date.prototype\")", true);
+        toBool.insert("engine->evaluate(\"Array.prototype\")", true);
+        toBool.insert("engine->evaluate(\"Function.prototype\")", true);
+        toBool.insert("engine->evaluate(\"Error.prototype\")", true);
+        toBool.insert("engine->evaluate(\"Object\")", true);
+        toBool.insert("engine->evaluate(\"Array\")", true);
+        toBool.insert("engine->evaluate(\"Number\")", true);
+        toBool.insert("engine->evaluate(\"Function\")", true);
+        toBool.insert("engine->evaluate(\"(function() { return 1; })\")", true);
+        toBool.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", true);
+        toBool.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", true);
+        toBool.insert("engine->evaluate(\"/foo/\")", true);
+        toBool.insert("engine->evaluate(\"new Object()\")", true);
+        toBool.insert("engine->evaluate(\"new Array()\")", true);
+        toBool.insert("engine->evaluate(\"new Error()\")", true);
+        toBool.insert("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", true);
+        toBool.insert("engine->evaluate(\"Undefined\")", true);
+        toBool.insert("engine->evaluate(\"Null\")", true);
+        toBool.insert("engine->evaluate(\"True\")", true);
+        toBool.insert("engine->evaluate(\"False\")", true);
+        toBool.insert("engine->evaluate(\"undefined\")", false);
+        toBool.insert("engine->evaluate(\"null\")", false);
+        toBool.insert("engine->evaluate(\"true\")", true);
+        toBool.insert("engine->evaluate(\"false\")", false);
+        toBool.insert("engine->evaluate(\"122\")", true);
+        toBool.insert("engine->evaluate(\"124\")", true);
+        toBool.insert("engine->evaluate(\"0\")", false);
+        toBool.insert("engine->evaluate(\"0.0\")", false);
+        toBool.insert("engine->evaluate(\"123.0\")", true);
+        toBool.insert("engine->evaluate(\"6.37e-8\")", true);
+        toBool.insert("engine->evaluate(\"-6.37e-8\")", true);
+        toBool.insert("engine->evaluate(\"0x43211234\")", true);
+        toBool.insert("engine->evaluate(\"0x10000\")", true);
+        toBool.insert("engine->evaluate(\"0x10001\")", true);
+        toBool.insert("engine->evaluate(\"NaN\")", false);
+        toBool.insert("engine->evaluate(\"Infinity\")", true);
+        toBool.insert("engine->evaluate(\"-Infinity\")", true);
+        toBool.insert("engine->evaluate(\"'ciao'\")", true);
+        toBool.insert("engine->evaluate(\"''\")", false);
+        toBool.insert("engine->evaluate(\"'0'\")", true);
+        toBool.insert("engine->evaluate(\"'123'\")", true);
+        toBool.insert("engine->evaluate(\"'12.4'\")", true);
+        toBool.insert("engine->nullValue()", false);
+        toBool.insert("engine->undefinedValue()", false);
+    }
+    newRow(expr) << toBool.value(expr);
+}
+
+void tst_QScriptValue::toBool_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.toBool(), expected);
+    QCOMPARE(value.toBool(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toBool)
+
+
+void tst_QScriptValue::toBoolean_initData()
+{
+    QTest::addColumn<bool>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::toBoolean_makeData(const char* expr)
+{
+    static QHash<QString, bool> toBoolean;
+    if (toBoolean.isEmpty()) {
+        toBoolean.insert("QScriptValue()", false);
+        toBoolean.insert("QScriptValue(QScriptValue::UndefinedValue)", false);
+        toBoolean.insert("QScriptValue(QScriptValue::NullValue)", false);
+        toBoolean.insert("QScriptValue(true)", true);
+        toBoolean.insert("QScriptValue(false)", false);
+        toBoolean.insert("QScriptValue(int(122))", true);
+        toBoolean.insert("QScriptValue(uint(124))", true);
+        toBoolean.insert("QScriptValue(0)", false);
+        toBoolean.insert("QScriptValue(0.0)", false);
+        toBoolean.insert("QScriptValue(123.0)", true);
+        toBoolean.insert("QScriptValue(6.37e-8)", true);
+        toBoolean.insert("QScriptValue(-6.37e-8)", true);
+        toBoolean.insert("QScriptValue(0x43211234)", true);
+        toBoolean.insert("QScriptValue(0x10000)", true);
+        toBoolean.insert("QScriptValue(0x10001)", true);
+        toBoolean.insert("QScriptValue(qSNaN())", false);
+        toBoolean.insert("QScriptValue(qQNaN())", false);
+        toBoolean.insert("QScriptValue(qInf())", true);
+        toBoolean.insert("QScriptValue(-qInf())", true);
+        toBoolean.insert("QScriptValue(\"NaN\")", true);
+        toBoolean.insert("QScriptValue(\"Infinity\")", true);
+        toBoolean.insert("QScriptValue(\"-Infinity\")", true);
+        toBoolean.insert("QScriptValue(\"ciao\")", true);
+        toBoolean.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", true);
+        toBoolean.insert("QScriptValue(QString(\"\"))", false);
+        toBoolean.insert("QScriptValue(QString())", false);
+        toBoolean.insert("QScriptValue(QString(\"0\"))", true);
+        toBoolean.insert("QScriptValue(QString(\"123\"))", true);
+        toBoolean.insert("QScriptValue(QString(\"12.4\"))", true);
+        toBoolean.insert("QScriptValue(0, QScriptValue::UndefinedValue)", false);
+        toBoolean.insert("QScriptValue(0, QScriptValue::NullValue)", false);
+        toBoolean.insert("QScriptValue(0, true)", true);
+        toBoolean.insert("QScriptValue(0, false)", false);
+        toBoolean.insert("QScriptValue(0, int(122))", true);
+        toBoolean.insert("QScriptValue(0, uint(124))", true);
+        toBoolean.insert("QScriptValue(0, 0)", false);
+        toBoolean.insert("QScriptValue(0, 0.0)", false);
+        toBoolean.insert("QScriptValue(0, 123.0)", true);
+        toBoolean.insert("QScriptValue(0, 6.37e-8)", true);
+        toBoolean.insert("QScriptValue(0, -6.37e-8)", true);
+        toBoolean.insert("QScriptValue(0, 0x43211234)", true);
+        toBoolean.insert("QScriptValue(0, 0x10000)", true);
+        toBoolean.insert("QScriptValue(0, 0x10001)", true);
+        toBoolean.insert("QScriptValue(0, qSNaN())", false);
+        toBoolean.insert("QScriptValue(0, qQNaN())", false);
+        toBoolean.insert("QScriptValue(0, qInf())", true);
+        toBoolean.insert("QScriptValue(0, -qInf())", true);
+        toBoolean.insert("QScriptValue(0, \"NaN\")", true);
+        toBoolean.insert("QScriptValue(0, \"Infinity\")", true);
+        toBoolean.insert("QScriptValue(0, \"-Infinity\")", true);
+        toBoolean.insert("QScriptValue(0, \"ciao\")", true);
+        toBoolean.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", true);
+        toBoolean.insert("QScriptValue(0, QString(\"\"))", false);
+        toBoolean.insert("QScriptValue(0, QString())", false);
+        toBoolean.insert("QScriptValue(0, QString(\"0\"))", true);
+        toBoolean.insert("QScriptValue(0, QString(\"123\"))", true);
+        toBoolean.insert("QScriptValue(0, QString(\"12.3\"))", true);
+        toBoolean.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", false);
+        toBoolean.insert("QScriptValue(engine, QScriptValue::NullValue)", false);
+        toBoolean.insert("QScriptValue(engine, true)", true);
+        toBoolean.insert("QScriptValue(engine, false)", false);
+        toBoolean.insert("QScriptValue(engine, int(122))", true);
+        toBoolean.insert("QScriptValue(engine, uint(124))", true);
+        toBoolean.insert("QScriptValue(engine, 0)", false);
+        toBoolean.insert("QScriptValue(engine, 0.0)", false);
+        toBoolean.insert("QScriptValue(engine, 123.0)", true);
+        toBoolean.insert("QScriptValue(engine, 6.37e-8)", true);
+        toBoolean.insert("QScriptValue(engine, -6.37e-8)", true);
+        toBoolean.insert("QScriptValue(engine, 0x43211234)", true);
+        toBoolean.insert("QScriptValue(engine, 0x10000)", true);
+        toBoolean.insert("QScriptValue(engine, 0x10001)", true);
+        toBoolean.insert("QScriptValue(engine, qSNaN())", false);
+        toBoolean.insert("QScriptValue(engine, qQNaN())", false);
+        toBoolean.insert("QScriptValue(engine, qInf())", true);
+        toBoolean.insert("QScriptValue(engine, -qInf())", true);
+        toBoolean.insert("QScriptValue(engine, \"NaN\")", true);
+        toBoolean.insert("QScriptValue(engine, \"Infinity\")", true);
+        toBoolean.insert("QScriptValue(engine, \"-Infinity\")", true);
+        toBoolean.insert("QScriptValue(engine, \"ciao\")", true);
+        toBoolean.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", true);
+        toBoolean.insert("QScriptValue(engine, QString(\"\"))", false);
+        toBoolean.insert("QScriptValue(engine, QString())", false);
+        toBoolean.insert("QScriptValue(engine, QString(\"0\"))", true);
+        toBoolean.insert("QScriptValue(engine, QString(\"123\"))", true);
+        toBoolean.insert("QScriptValue(engine, QString(\"1.23\"))", true);
+        toBoolean.insert("engine->evaluate(\"[]\")", true);
+        toBoolean.insert("engine->evaluate(\"{}\")", false);
+        toBoolean.insert("engine->evaluate(\"Object.prototype\")", true);
+        toBoolean.insert("engine->evaluate(\"Date.prototype\")", true);
+        toBoolean.insert("engine->evaluate(\"Array.prototype\")", true);
+        toBoolean.insert("engine->evaluate(\"Function.prototype\")", true);
+        toBoolean.insert("engine->evaluate(\"Error.prototype\")", true);
+        toBoolean.insert("engine->evaluate(\"Object\")", true);
+        toBoolean.insert("engine->evaluate(\"Array\")", true);
+        toBoolean.insert("engine->evaluate(\"Number\")", true);
+        toBoolean.insert("engine->evaluate(\"Function\")", true);
+        toBoolean.insert("engine->evaluate(\"(function() { return 1; })\")", true);
+        toBoolean.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", true);
+        toBoolean.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", true);
+        toBoolean.insert("engine->evaluate(\"/foo/\")", true);
+        toBoolean.insert("engine->evaluate(\"new Object()\")", true);
+        toBoolean.insert("engine->evaluate(\"new Array()\")", true);
+        toBoolean.insert("engine->evaluate(\"new Error()\")", true);
+        toBoolean.insert("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", true);
+        toBoolean.insert("engine->evaluate(\"Undefined\")", true);
+        toBoolean.insert("engine->evaluate(\"Null\")", true);
+        toBoolean.insert("engine->evaluate(\"True\")", true);
+        toBoolean.insert("engine->evaluate(\"False\")", true);
+        toBoolean.insert("engine->evaluate(\"undefined\")", false);
+        toBoolean.insert("engine->evaluate(\"null\")", false);
+        toBoolean.insert("engine->evaluate(\"true\")", true);
+        toBoolean.insert("engine->evaluate(\"false\")", false);
+        toBoolean.insert("engine->evaluate(\"122\")", true);
+        toBoolean.insert("engine->evaluate(\"124\")", true);
+        toBoolean.insert("engine->evaluate(\"0\")", false);
+        toBoolean.insert("engine->evaluate(\"0.0\")", false);
+        toBoolean.insert("engine->evaluate(\"123.0\")", true);
+        toBoolean.insert("engine->evaluate(\"6.37e-8\")", true);
+        toBoolean.insert("engine->evaluate(\"-6.37e-8\")", true);
+        toBoolean.insert("engine->evaluate(\"0x43211234\")", true);
+        toBoolean.insert("engine->evaluate(\"0x10000\")", true);
+        toBoolean.insert("engine->evaluate(\"0x10001\")", true);
+        toBoolean.insert("engine->evaluate(\"NaN\")", false);
+        toBoolean.insert("engine->evaluate(\"Infinity\")", true);
+        toBoolean.insert("engine->evaluate(\"-Infinity\")", true);
+        toBoolean.insert("engine->evaluate(\"'ciao'\")", true);
+        toBoolean.insert("engine->evaluate(\"''\")", false);
+        toBoolean.insert("engine->evaluate(\"'0'\")", true);
+        toBoolean.insert("engine->evaluate(\"'123'\")", true);
+        toBoolean.insert("engine->evaluate(\"'12.4'\")", true);
+        toBoolean.insert("engine->nullValue()", false);
+        toBoolean.insert("engine->undefinedValue()", false);
+    }
+    newRow(expr) << toBoolean.value(expr);
+}
+
+void tst_QScriptValue::toBoolean_test(const char*, const QScriptValue& value)
+{
+    QFETCH(bool, expected);
+    QCOMPARE(value.toBoolean(), expected);
+    QCOMPARE(value.toBoolean(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toBoolean)
+
+
+void tst_QScriptValue::toInteger_initData()
+{
+    QTest::addColumn<qsreal>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::toInteger_makeData(const char* expr)
+{
+    static QHash<QString, qsreal> toInteger;
+    if (toInteger.isEmpty()) {
+        toInteger.insert("QScriptValue()", 0);
+        toInteger.insert("QScriptValue(QScriptValue::UndefinedValue)", 0);
+        toInteger.insert("QScriptValue(QScriptValue::NullValue)", 0);
+        toInteger.insert("QScriptValue(true)", 1);
+        toInteger.insert("QScriptValue(false)", 0);
+        toInteger.insert("QScriptValue(int(122))", 122);
+        toInteger.insert("QScriptValue(uint(124))", 124);
+        toInteger.insert("QScriptValue(0)", 0);
+        toInteger.insert("QScriptValue(0.0)", 0);
+        toInteger.insert("QScriptValue(123.0)", 123);
+        toInteger.insert("QScriptValue(6.37e-8)", 0);
+        toInteger.insert("QScriptValue(-6.37e-8)", 0);
+        toInteger.insert("QScriptValue(0x43211234)", 1126240820);
+        toInteger.insert("QScriptValue(0x10000)", 65536);
+        toInteger.insert("QScriptValue(0x10001)", 65537);
+        toInteger.insert("QScriptValue(qSNaN())", 0);
+        toInteger.insert("QScriptValue(qQNaN())", 0);
+        toInteger.insert("QScriptValue(qInf())", qInf());
+        toInteger.insert("QScriptValue(-qInf())", qInf());
+        toInteger.insert("QScriptValue(\"NaN\")", 0);
+        toInteger.insert("QScriptValue(\"Infinity\")", qInf());
+        toInteger.insert("QScriptValue(\"-Infinity\")", qInf());
+        toInteger.insert("QScriptValue(\"ciao\")", 0);
+        toInteger.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", 0);
+        toInteger.insert("QScriptValue(QString(\"\"))", 0);
+        toInteger.insert("QScriptValue(QString())", 0);
+        toInteger.insert("QScriptValue(QString(\"0\"))", 0);
+        toInteger.insert("QScriptValue(QString(\"123\"))", 123);
+        toInteger.insert("QScriptValue(QString(\"12.4\"))", 12);
+        toInteger.insert("QScriptValue(0, QScriptValue::UndefinedValue)", 0);
+        toInteger.insert("QScriptValue(0, QScriptValue::NullValue)", 0);
+        toInteger.insert("QScriptValue(0, true)", 1);
+        toInteger.insert("QScriptValue(0, false)", 0);
+        toInteger.insert("QScriptValue(0, int(122))", 122);
+        toInteger.insert("QScriptValue(0, uint(124))", 124);
+        toInteger.insert("QScriptValue(0, 0)", 0);
+        toInteger.insert("QScriptValue(0, 0.0)", 0);
+        toInteger.insert("QScriptValue(0, 123.0)", 123);
+        toInteger.insert("QScriptValue(0, 6.37e-8)", 0);
+        toInteger.insert("QScriptValue(0, -6.37e-8)", 0);
+        toInteger.insert("QScriptValue(0, 0x43211234)", 1126240820);
+        toInteger.insert("QScriptValue(0, 0x10000)", 65536);
+        toInteger.insert("QScriptValue(0, 0x10001)", 65537);
+        toInteger.insert("QScriptValue(0, qSNaN())", 0);
+        toInteger.insert("QScriptValue(0, qQNaN())", 0);
+        toInteger.insert("QScriptValue(0, qInf())", qInf());
+        toInteger.insert("QScriptValue(0, -qInf())", qInf());
+        toInteger.insert("QScriptValue(0, \"NaN\")", 0);
+        toInteger.insert("QScriptValue(0, \"Infinity\")", qInf());
+        toInteger.insert("QScriptValue(0, \"-Infinity\")", qInf());
+        toInteger.insert("QScriptValue(0, \"ciao\")", 0);
+        toInteger.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", 0);
+        toInteger.insert("QScriptValue(0, QString(\"\"))", 0);
+        toInteger.insert("QScriptValue(0, QString())", 0);
+        toInteger.insert("QScriptValue(0, QString(\"0\"))", 0);
+        toInteger.insert("QScriptValue(0, QString(\"123\"))", 123);
+        toInteger.insert("QScriptValue(0, QString(\"12.3\"))", 12);
+        toInteger.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", 0);
+        toInteger.insert("QScriptValue(engine, QScriptValue::NullValue)", 0);
+        toInteger.insert("QScriptValue(engine, true)", 1);
+        toInteger.insert("QScriptValue(engine, false)", 0);
+        toInteger.insert("QScriptValue(engine, int(122))", 122);
+        toInteger.insert("QScriptValue(engine, uint(124))", 124);
+        toInteger.insert("QScriptValue(engine, 0)", 0);
+        toInteger.insert("QScriptValue(engine, 0.0)", 0);
+        toInteger.insert("QScriptValue(engine, 123.0)", 123);
+        toInteger.insert("QScriptValue(engine, 6.37e-8)", 0);
+        toInteger.insert("QScriptValue(engine, -6.37e-8)", 0);
+        toInteger.insert("QScriptValue(engine, 0x43211234)", 1126240820);
+        toInteger.insert("QScriptValue(engine, 0x10000)", 65536);
+        toInteger.insert("QScriptValue(engine, 0x10001)", 65537);
+        toInteger.insert("QScriptValue(engine, qSNaN())", 0);
+        toInteger.insert("QScriptValue(engine, qQNaN())", 0);
+        toInteger.insert("QScriptValue(engine, qInf())", qInf());
+        toInteger.insert("QScriptValue(engine, -qInf())", qInf());
+        toInteger.insert("QScriptValue(engine, \"NaN\")", 0);
+        toInteger.insert("QScriptValue(engine, \"Infinity\")", qInf());
+        toInteger.insert("QScriptValue(engine, \"-Infinity\")", qInf());
+        toInteger.insert("QScriptValue(engine, \"ciao\")", 0);
+        toInteger.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", 0);
+        toInteger.insert("QScriptValue(engine, QString(\"\"))", 0);
+        toInteger.insert("QScriptValue(engine, QString())", 0);
+        toInteger.insert("QScriptValue(engine, QString(\"0\"))", 0);
+        toInteger.insert("QScriptValue(engine, QString(\"123\"))", 123);
+        toInteger.insert("QScriptValue(engine, QString(\"1.23\"))", 1);
+        toInteger.insert("engine->evaluate(\"[]\")", 0);
+        toInteger.insert("engine->evaluate(\"{}\")", 0);
+        toInteger.insert("engine->evaluate(\"Object.prototype\")", 0);
+        toInteger.insert("engine->evaluate(\"Date.prototype\")", 0);
+        toInteger.insert("engine->evaluate(\"Array.prototype\")", 0);
+        toInteger.insert("engine->evaluate(\"Function.prototype\")", 0);
+        toInteger.insert("engine->evaluate(\"Error.prototype\")", 0);
+        toInteger.insert("engine->evaluate(\"Object\")", 0);
+        toInteger.insert("engine->evaluate(\"Array\")", 0);
+        toInteger.insert("engine->evaluate(\"Number\")", 0);
+        toInteger.insert("engine->evaluate(\"Function\")", 0);
+        toInteger.insert("engine->evaluate(\"(function() { return 1; })\")", 0);
+        toInteger.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", 0);
+        toInteger.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", 0);
+        toInteger.insert("engine->evaluate(\"/foo/\")", 0);
+        toInteger.insert("engine->evaluate(\"new Object()\")", 0);
+        toInteger.insert("engine->evaluate(\"new Array()\")", 0);
+        toInteger.insert("engine->evaluate(\"new Error()\")", 0);
+        toInteger.insert("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", 22);
+        toInteger.insert("engine->evaluate(\"Undefined\")", 0);
+        toInteger.insert("engine->evaluate(\"Null\")", 0);
+        toInteger.insert("engine->evaluate(\"True\")", 0);
+        toInteger.insert("engine->evaluate(\"False\")", 0);
+        toInteger.insert("engine->evaluate(\"undefined\")", 0);
+        toInteger.insert("engine->evaluate(\"null\")", 0);
+        toInteger.insert("engine->evaluate(\"true\")", 1);
+        toInteger.insert("engine->evaluate(\"false\")", 0);
+        toInteger.insert("engine->evaluate(\"122\")", 122);
+        toInteger.insert("engine->evaluate(\"124\")", 124);
+        toInteger.insert("engine->evaluate(\"0\")", 0);
+        toInteger.insert("engine->evaluate(\"0.0\")", 0);
+        toInteger.insert("engine->evaluate(\"123.0\")", 123);
+        toInteger.insert("engine->evaluate(\"6.37e-8\")", 0);
+        toInteger.insert("engine->evaluate(\"-6.37e-8\")", 0);
+        toInteger.insert("engine->evaluate(\"0x43211234\")", 1126240820);
+        toInteger.insert("engine->evaluate(\"0x10000\")", 65536);
+        toInteger.insert("engine->evaluate(\"0x10001\")", 65537);
+        toInteger.insert("engine->evaluate(\"NaN\")", 0);
+        toInteger.insert("engine->evaluate(\"Infinity\")", qInf());
+        toInteger.insert("engine->evaluate(\"-Infinity\")", qInf());
+        toInteger.insert("engine->evaluate(\"'ciao'\")", 0);
+        toInteger.insert("engine->evaluate(\"''\")", 0);
+        toInteger.insert("engine->evaluate(\"'0'\")", 0);
+        toInteger.insert("engine->evaluate(\"'123'\")", 123);
+        toInteger.insert("engine->evaluate(\"'12.4'\")", 12);
+        toInteger.insert("engine->nullValue()", 0);
+        toInteger.insert("engine->undefinedValue()", 0);
+    }
+    newRow(expr) << toInteger.value(expr);
+}
+
+void tst_QScriptValue::toInteger_test(const char*, const QScriptValue& value)
+{
+    QFETCH(qsreal, expected);
+    if (qIsInf(expected)) {
+        QVERIFY(qIsInf(value.toInteger()));
+        QVERIFY(qIsInf(value.toInteger()));
+        return;
+    }
+    QCOMPARE(value.toInteger(), expected);
+    QCOMPARE(value.toInteger(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toInteger)
+
+
+void tst_QScriptValue::toInt32_initData()
+{
+    QTest::addColumn<qint32>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::toInt32_makeData(const char* expr)
+{
+    static QHash<QString, qint32> toInt32;
+    if (toInt32.isEmpty()) {
+        toInt32.insert("QScriptValue()", 0);
+        toInt32.insert("QScriptValue(QScriptValue::UndefinedValue)", 0);
+        toInt32.insert("QScriptValue(QScriptValue::NullValue)", 0);
+        toInt32.insert("QScriptValue(true)", 1);
+        toInt32.insert("QScriptValue(false)", 0);
+        toInt32.insert("QScriptValue(int(122))", 122);
+        toInt32.insert("QScriptValue(uint(124))", 124);
+        toInt32.insert("QScriptValue(0)", 0);
+        toInt32.insert("QScriptValue(0.0)", 0);
+        toInt32.insert("QScriptValue(123.0)", 123);
+        toInt32.insert("QScriptValue(6.37e-8)", 0);
+        toInt32.insert("QScriptValue(-6.37e-8)", 0);
+        toInt32.insert("QScriptValue(0x43211234)", 1126240820);
+        toInt32.insert("QScriptValue(0x10000)", 65536);
+        toInt32.insert("QScriptValue(0x10001)", 65537);
+        toInt32.insert("QScriptValue(qSNaN())", 0);
+        toInt32.insert("QScriptValue(qQNaN())", 0);
+        toInt32.insert("QScriptValue(qInf())", 0);
+        toInt32.insert("QScriptValue(-qInf())", 0);
+        toInt32.insert("QScriptValue(\"NaN\")", 0);
+        toInt32.insert("QScriptValue(\"Infinity\")", 0);
+        toInt32.insert("QScriptValue(\"-Infinity\")", 0);
+        toInt32.insert("QScriptValue(\"ciao\")", 0);
+        toInt32.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", 0);
+        toInt32.insert("QScriptValue(QString(\"\"))", 0);
+        toInt32.insert("QScriptValue(QString())", 0);
+        toInt32.insert("QScriptValue(QString(\"0\"))", 0);
+        toInt32.insert("QScriptValue(QString(\"123\"))", 123);
+        toInt32.insert("QScriptValue(QString(\"12.4\"))", 12);
+        toInt32.insert("QScriptValue(0, QScriptValue::UndefinedValue)", 0);
+        toInt32.insert("QScriptValue(0, QScriptValue::NullValue)", 0);
+        toInt32.insert("QScriptValue(0, true)", 1);
+        toInt32.insert("QScriptValue(0, false)", 0);
+        toInt32.insert("QScriptValue(0, int(122))", 122);
+        toInt32.insert("QScriptValue(0, uint(124))", 124);
+        toInt32.insert("QScriptValue(0, 0)", 0);
+        toInt32.insert("QScriptValue(0, 0.0)", 0);
+        toInt32.insert("QScriptValue(0, 123.0)", 123);
+        toInt32.insert("QScriptValue(0, 6.37e-8)", 0);
+        toInt32.insert("QScriptValue(0, -6.37e-8)", 0);
+        toInt32.insert("QScriptValue(0, 0x43211234)", 1126240820);
+        toInt32.insert("QScriptValue(0, 0x10000)", 65536);
+        toInt32.insert("QScriptValue(0, 0x10001)", 65537);
+        toInt32.insert("QScriptValue(0, qSNaN())", 0);
+        toInt32.insert("QScriptValue(0, qQNaN())", 0);
+        toInt32.insert("QScriptValue(0, qInf())", 0);
+        toInt32.insert("QScriptValue(0, -qInf())", 0);
+        toInt32.insert("QScriptValue(0, \"NaN\")", 0);
+        toInt32.insert("QScriptValue(0, \"Infinity\")", 0);
+        toInt32.insert("QScriptValue(0, \"-Infinity\")", 0);
+        toInt32.insert("QScriptValue(0, \"ciao\")", 0);
+        toInt32.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", 0);
+        toInt32.insert("QScriptValue(0, QString(\"\"))", 0);
+        toInt32.insert("QScriptValue(0, QString())", 0);
+        toInt32.insert("QScriptValue(0, QString(\"0\"))", 0);
+        toInt32.insert("QScriptValue(0, QString(\"123\"))", 123);
+        toInt32.insert("QScriptValue(0, QString(\"12.3\"))", 12);
+        toInt32.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", 0);
+        toInt32.insert("QScriptValue(engine, QScriptValue::NullValue)", 0);
+        toInt32.insert("QScriptValue(engine, true)", 1);
+        toInt32.insert("QScriptValue(engine, false)", 0);
+        toInt32.insert("QScriptValue(engine, int(122))", 122);
+        toInt32.insert("QScriptValue(engine, uint(124))", 124);
+        toInt32.insert("QScriptValue(engine, 0)", 0);
+        toInt32.insert("QScriptValue(engine, 0.0)", 0);
+        toInt32.insert("QScriptValue(engine, 123.0)", 123);
+        toInt32.insert("QScriptValue(engine, 6.37e-8)", 0);
+        toInt32.insert("QScriptValue(engine, -6.37e-8)", 0);
+        toInt32.insert("QScriptValue(engine, 0x43211234)", 1126240820);
+        toInt32.insert("QScriptValue(engine, 0x10000)", 65536);
+        toInt32.insert("QScriptValue(engine, 0x10001)", 65537);
+        toInt32.insert("QScriptValue(engine, qSNaN())", 0);
+        toInt32.insert("QScriptValue(engine, qQNaN())", 0);
+        toInt32.insert("QScriptValue(engine, qInf())", 0);
+        toInt32.insert("QScriptValue(engine, -qInf())", 0);
+        toInt32.insert("QScriptValue(engine, \"NaN\")", 0);
+        toInt32.insert("QScriptValue(engine, \"Infinity\")", 0);
+        toInt32.insert("QScriptValue(engine, \"-Infinity\")", 0);
+        toInt32.insert("QScriptValue(engine, \"ciao\")", 0);
+        toInt32.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", 0);
+        toInt32.insert("QScriptValue(engine, QString(\"\"))", 0);
+        toInt32.insert("QScriptValue(engine, QString())", 0);
+        toInt32.insert("QScriptValue(engine, QString(\"0\"))", 0);
+        toInt32.insert("QScriptValue(engine, QString(\"123\"))", 123);
+        toInt32.insert("QScriptValue(engine, QString(\"1.23\"))", 1);
+        toInt32.insert("engine->evaluate(\"[]\")", 0);
+        toInt32.insert("engine->evaluate(\"{}\")", 0);
+        toInt32.insert("engine->evaluate(\"Object.prototype\")", 0);
+        toInt32.insert("engine->evaluate(\"Date.prototype\")", 0);
+        toInt32.insert("engine->evaluate(\"Array.prototype\")", 0);
+        toInt32.insert("engine->evaluate(\"Function.prototype\")", 0);
+        toInt32.insert("engine->evaluate(\"Error.prototype\")", 0);
+        toInt32.insert("engine->evaluate(\"Object\")", 0);
+        toInt32.insert("engine->evaluate(\"Array\")", 0);
+        toInt32.insert("engine->evaluate(\"Number\")", 0);
+        toInt32.insert("engine->evaluate(\"Function\")", 0);
+        toInt32.insert("engine->evaluate(\"(function() { return 1; })\")", 0);
+        toInt32.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", 0);
+        toInt32.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", 0);
+        toInt32.insert("engine->evaluate(\"/foo/\")", 0);
+        toInt32.insert("engine->evaluate(\"new Object()\")", 0);
+        toInt32.insert("engine->evaluate(\"new Array()\")", 0);
+        toInt32.insert("engine->evaluate(\"new Error()\")", 0);
+        toInt32.insert("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", 22);
+        toInt32.insert("engine->evaluate(\"Undefined\")", 0);
+        toInt32.insert("engine->evaluate(\"Null\")", 0);
+        toInt32.insert("engine->evaluate(\"True\")", 0);
+        toInt32.insert("engine->evaluate(\"False\")", 0);
+        toInt32.insert("engine->evaluate(\"undefined\")", 0);
+        toInt32.insert("engine->evaluate(\"null\")", 0);
+        toInt32.insert("engine->evaluate(\"true\")", 1);
+        toInt32.insert("engine->evaluate(\"false\")", 0);
+        toInt32.insert("engine->evaluate(\"122\")", 122);
+        toInt32.insert("engine->evaluate(\"124\")", 124);
+        toInt32.insert("engine->evaluate(\"0\")", 0);
+        toInt32.insert("engine->evaluate(\"0.0\")", 0);
+        toInt32.insert("engine->evaluate(\"123.0\")", 123);
+        toInt32.insert("engine->evaluate(\"6.37e-8\")", 0);
+        toInt32.insert("engine->evaluate(\"-6.37e-8\")", 0);
+        toInt32.insert("engine->evaluate(\"0x43211234\")", 1126240820);
+        toInt32.insert("engine->evaluate(\"0x10000\")", 65536);
+        toInt32.insert("engine->evaluate(\"0x10001\")", 65537);
+        toInt32.insert("engine->evaluate(\"NaN\")", 0);
+        toInt32.insert("engine->evaluate(\"Infinity\")", 0);
+        toInt32.insert("engine->evaluate(\"-Infinity\")", 0);
+        toInt32.insert("engine->evaluate(\"'ciao'\")", 0);
+        toInt32.insert("engine->evaluate(\"''\")", 0);
+        toInt32.insert("engine->evaluate(\"'0'\")", 0);
+        toInt32.insert("engine->evaluate(\"'123'\")", 123);
+        toInt32.insert("engine->evaluate(\"'12.4'\")", 12);
+        toInt32.insert("engine->nullValue()", 0);
+        toInt32.insert("engine->undefinedValue()", 0);
+    }
+    newRow(expr) << toInt32.value(expr);
+}
+
+void tst_QScriptValue::toInt32_test(const char*, const QScriptValue& value)
+{
+    QFETCH(qint32, expected);
+    QCOMPARE(value.toInt32(), expected);
+    QCOMPARE(value.toInt32(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toInt32)
+
+
+void tst_QScriptValue::toUInt32_initData()
+{
+    QTest::addColumn<quint32>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::toUInt32_makeData(const char* expr)
+{
+    static QHash<QString, quint32> toUInt32;
+    if (toUInt32.isEmpty()) {
+        toUInt32.insert("QScriptValue()", 0);
+        toUInt32.insert("QScriptValue(QScriptValue::UndefinedValue)", 0);
+        toUInt32.insert("QScriptValue(QScriptValue::NullValue)", 0);
+        toUInt32.insert("QScriptValue(true)", 1);
+        toUInt32.insert("QScriptValue(false)", 0);
+        toUInt32.insert("QScriptValue(int(122))", 122);
+        toUInt32.insert("QScriptValue(uint(124))", 124);
+        toUInt32.insert("QScriptValue(0)", 0);
+        toUInt32.insert("QScriptValue(0.0)", 0);
+        toUInt32.insert("QScriptValue(123.0)", 123);
+        toUInt32.insert("QScriptValue(6.37e-8)", 0);
+        toUInt32.insert("QScriptValue(-6.37e-8)", 0);
+        toUInt32.insert("QScriptValue(0x43211234)", 1126240820);
+        toUInt32.insert("QScriptValue(0x10000)", 65536);
+        toUInt32.insert("QScriptValue(0x10001)", 65537);
+        toUInt32.insert("QScriptValue(qSNaN())", 0);
+        toUInt32.insert("QScriptValue(qQNaN())", 0);
+        toUInt32.insert("QScriptValue(qInf())", 0);
+        toUInt32.insert("QScriptValue(-qInf())", 0);
+        toUInt32.insert("QScriptValue(\"NaN\")", 0);
+        toUInt32.insert("QScriptValue(\"Infinity\")", 0);
+        toUInt32.insert("QScriptValue(\"-Infinity\")", 0);
+        toUInt32.insert("QScriptValue(\"ciao\")", 0);
+        toUInt32.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", 0);
+        toUInt32.insert("QScriptValue(QString(\"\"))", 0);
+        toUInt32.insert("QScriptValue(QString())", 0);
+        toUInt32.insert("QScriptValue(QString(\"0\"))", 0);
+        toUInt32.insert("QScriptValue(QString(\"123\"))", 123);
+        toUInt32.insert("QScriptValue(QString(\"12.4\"))", 12);
+        toUInt32.insert("QScriptValue(0, QScriptValue::UndefinedValue)", 0);
+        toUInt32.insert("QScriptValue(0, QScriptValue::NullValue)", 0);
+        toUInt32.insert("QScriptValue(0, true)", 1);
+        toUInt32.insert("QScriptValue(0, false)", 0);
+        toUInt32.insert("QScriptValue(0, int(122))", 122);
+        toUInt32.insert("QScriptValue(0, uint(124))", 124);
+        toUInt32.insert("QScriptValue(0, 0)", 0);
+        toUInt32.insert("QScriptValue(0, 0.0)", 0);
+        toUInt32.insert("QScriptValue(0, 123.0)", 123);
+        toUInt32.insert("QScriptValue(0, 6.37e-8)", 0);
+        toUInt32.insert("QScriptValue(0, -6.37e-8)", 0);
+        toUInt32.insert("QScriptValue(0, 0x43211234)", 1126240820);
+        toUInt32.insert("QScriptValue(0, 0x10000)", 65536);
+        toUInt32.insert("QScriptValue(0, 0x10001)", 65537);
+        toUInt32.insert("QScriptValue(0, qSNaN())", 0);
+        toUInt32.insert("QScriptValue(0, qQNaN())", 0);
+        toUInt32.insert("QScriptValue(0, qInf())", 0);
+        toUInt32.insert("QScriptValue(0, -qInf())", 0);
+        toUInt32.insert("QScriptValue(0, \"NaN\")", 0);
+        toUInt32.insert("QScriptValue(0, \"Infinity\")", 0);
+        toUInt32.insert("QScriptValue(0, \"-Infinity\")", 0);
+        toUInt32.insert("QScriptValue(0, \"ciao\")", 0);
+        toUInt32.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", 0);
+        toUInt32.insert("QScriptValue(0, QString(\"\"))", 0);
+        toUInt32.insert("QScriptValue(0, QString())", 0);
+        toUInt32.insert("QScriptValue(0, QString(\"0\"))", 0);
+        toUInt32.insert("QScriptValue(0, QString(\"123\"))", 123);
+        toUInt32.insert("QScriptValue(0, QString(\"12.3\"))", 12);
+        toUInt32.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", 0);
+        toUInt32.insert("QScriptValue(engine, QScriptValue::NullValue)", 0);
+        toUInt32.insert("QScriptValue(engine, true)", 1);
+        toUInt32.insert("QScriptValue(engine, false)", 0);
+        toUInt32.insert("QScriptValue(engine, int(122))", 122);
+        toUInt32.insert("QScriptValue(engine, uint(124))", 124);
+        toUInt32.insert("QScriptValue(engine, 0)", 0);
+        toUInt32.insert("QScriptValue(engine, 0.0)", 0);
+        toUInt32.insert("QScriptValue(engine, 123.0)", 123);
+        toUInt32.insert("QScriptValue(engine, 6.37e-8)", 0);
+        toUInt32.insert("QScriptValue(engine, -6.37e-8)", 0);
+        toUInt32.insert("QScriptValue(engine, 0x43211234)", 1126240820);
+        toUInt32.insert("QScriptValue(engine, 0x10000)", 65536);
+        toUInt32.insert("QScriptValue(engine, 0x10001)", 65537);
+        toUInt32.insert("QScriptValue(engine, qSNaN())", 0);
+        toUInt32.insert("QScriptValue(engine, qQNaN())", 0);
+        toUInt32.insert("QScriptValue(engine, qInf())", 0);
+        toUInt32.insert("QScriptValue(engine, -qInf())", 0);
+        toUInt32.insert("QScriptValue(engine, \"NaN\")", 0);
+        toUInt32.insert("QScriptValue(engine, \"Infinity\")", 0);
+        toUInt32.insert("QScriptValue(engine, \"-Infinity\")", 0);
+        toUInt32.insert("QScriptValue(engine, \"ciao\")", 0);
+        toUInt32.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", 0);
+        toUInt32.insert("QScriptValue(engine, QString(\"\"))", 0);
+        toUInt32.insert("QScriptValue(engine, QString())", 0);
+        toUInt32.insert("QScriptValue(engine, QString(\"0\"))", 0);
+        toUInt32.insert("QScriptValue(engine, QString(\"123\"))", 123);
+        toUInt32.insert("QScriptValue(engine, QString(\"1.23\"))", 1);
+        toUInt32.insert("engine->evaluate(\"[]\")", 0);
+        toUInt32.insert("engine->evaluate(\"{}\")", 0);
+        toUInt32.insert("engine->evaluate(\"Object.prototype\")", 0);
+        toUInt32.insert("engine->evaluate(\"Date.prototype\")", 0);
+        toUInt32.insert("engine->evaluate(\"Array.prototype\")", 0);
+        toUInt32.insert("engine->evaluate(\"Function.prototype\")", 0);
+        toUInt32.insert("engine->evaluate(\"Error.prototype\")", 0);
+        toUInt32.insert("engine->evaluate(\"Object\")", 0);
+        toUInt32.insert("engine->evaluate(\"Array\")", 0);
+        toUInt32.insert("engine->evaluate(\"Number\")", 0);
+        toUInt32.insert("engine->evaluate(\"Function\")", 0);
+        toUInt32.insert("engine->evaluate(\"(function() { return 1; })\")", 0);
+        toUInt32.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", 0);
+        toUInt32.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", 0);
+        toUInt32.insert("engine->evaluate(\"/foo/\")", 0);
+        toUInt32.insert("engine->evaluate(\"new Object()\")", 0);
+        toUInt32.insert("engine->evaluate(\"new Array()\")", 0);
+        toUInt32.insert("engine->evaluate(\"new Error()\")", 0);
+        toUInt32.insert("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", 22);
+        toUInt32.insert("engine->evaluate(\"Undefined\")", 0);
+        toUInt32.insert("engine->evaluate(\"Null\")", 0);
+        toUInt32.insert("engine->evaluate(\"True\")", 0);
+        toUInt32.insert("engine->evaluate(\"False\")", 0);
+        toUInt32.insert("engine->evaluate(\"undefined\")", 0);
+        toUInt32.insert("engine->evaluate(\"null\")", 0);
+        toUInt32.insert("engine->evaluate(\"true\")", 1);
+        toUInt32.insert("engine->evaluate(\"false\")", 0);
+        toUInt32.insert("engine->evaluate(\"122\")", 122);
+        toUInt32.insert("engine->evaluate(\"124\")", 124);
+        toUInt32.insert("engine->evaluate(\"0\")", 0);
+        toUInt32.insert("engine->evaluate(\"0.0\")", 0);
+        toUInt32.insert("engine->evaluate(\"123.0\")", 123);
+        toUInt32.insert("engine->evaluate(\"6.37e-8\")", 0);
+        toUInt32.insert("engine->evaluate(\"-6.37e-8\")", 0);
+        toUInt32.insert("engine->evaluate(\"0x43211234\")", 1126240820);
+        toUInt32.insert("engine->evaluate(\"0x10000\")", 65536);
+        toUInt32.insert("engine->evaluate(\"0x10001\")", 65537);
+        toUInt32.insert("engine->evaluate(\"NaN\")", 0);
+        toUInt32.insert("engine->evaluate(\"Infinity\")", 0);
+        toUInt32.insert("engine->evaluate(\"-Infinity\")", 0);
+        toUInt32.insert("engine->evaluate(\"'ciao'\")", 0);
+        toUInt32.insert("engine->evaluate(\"''\")", 0);
+        toUInt32.insert("engine->evaluate(\"'0'\")", 0);
+        toUInt32.insert("engine->evaluate(\"'123'\")", 123);
+        toUInt32.insert("engine->evaluate(\"'12.4'\")", 12);
+        toUInt32.insert("engine->nullValue()", 0);
+        toUInt32.insert("engine->undefinedValue()", 0);
+    }
+    newRow(expr) << toUInt32.value(expr);
+}
+
+void tst_QScriptValue::toUInt32_test(const char*, const QScriptValue& value)
+{
+    QFETCH(quint32, expected);
+    QCOMPARE(value.toUInt32(), expected);
+    QCOMPARE(value.toUInt32(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toUInt32)
+
+
+void tst_QScriptValue::toUInt16_initData()
+{
+    QTest::addColumn<quint16>("expected");
+    initScriptValues();
+}
+
+void tst_QScriptValue::toUInt16_makeData(const char* expr)
+{
+    static QHash<QString, quint16> toUInt16;
+    if (toUInt16.isEmpty()) {
+        toUInt16.insert("QScriptValue()", 0);
+        toUInt16.insert("QScriptValue(QScriptValue::UndefinedValue)", 0);
+        toUInt16.insert("QScriptValue(QScriptValue::NullValue)", 0);
+        toUInt16.insert("QScriptValue(true)", 1);
+        toUInt16.insert("QScriptValue(false)", 0);
+        toUInt16.insert("QScriptValue(int(122))", 122);
+        toUInt16.insert("QScriptValue(uint(124))", 124);
+        toUInt16.insert("QScriptValue(0)", 0);
+        toUInt16.insert("QScriptValue(0.0)", 0);
+        toUInt16.insert("QScriptValue(123.0)", 123);
+        toUInt16.insert("QScriptValue(6.37e-8)", 0);
+        toUInt16.insert("QScriptValue(-6.37e-8)", 0);
+        toUInt16.insert("QScriptValue(0x43211234)", 4660);
+        toUInt16.insert("QScriptValue(0x10000)", 0);
+        toUInt16.insert("QScriptValue(0x10001)", 1);
+        toUInt16.insert("QScriptValue(qSNaN())", 0);
+        toUInt16.insert("QScriptValue(qQNaN())", 0);
+        toUInt16.insert("QScriptValue(qInf())", 0);
+        toUInt16.insert("QScriptValue(-qInf())", 0);
+        toUInt16.insert("QScriptValue(\"NaN\")", 0);
+        toUInt16.insert("QScriptValue(\"Infinity\")", 0);
+        toUInt16.insert("QScriptValue(\"-Infinity\")", 0);
+        toUInt16.insert("QScriptValue(\"ciao\")", 0);
+        toUInt16.insert("QScriptValue(QString::fromLatin1(\"ciao\"))", 0);
+        toUInt16.insert("QScriptValue(QString(\"\"))", 0);
+        toUInt16.insert("QScriptValue(QString())", 0);
+        toUInt16.insert("QScriptValue(QString(\"0\"))", 0);
+        toUInt16.insert("QScriptValue(QString(\"123\"))", 123);
+        toUInt16.insert("QScriptValue(QString(\"12.4\"))", 12);
+        toUInt16.insert("QScriptValue(0, QScriptValue::UndefinedValue)", 0);
+        toUInt16.insert("QScriptValue(0, QScriptValue::NullValue)", 0);
+        toUInt16.insert("QScriptValue(0, true)", 1);
+        toUInt16.insert("QScriptValue(0, false)", 0);
+        toUInt16.insert("QScriptValue(0, int(122))", 122);
+        toUInt16.insert("QScriptValue(0, uint(124))", 124);
+        toUInt16.insert("QScriptValue(0, 0)", 0);
+        toUInt16.insert("QScriptValue(0, 0.0)", 0);
+        toUInt16.insert("QScriptValue(0, 123.0)", 123);
+        toUInt16.insert("QScriptValue(0, 6.37e-8)", 0);
+        toUInt16.insert("QScriptValue(0, -6.37e-8)", 0);
+        toUInt16.insert("QScriptValue(0, 0x43211234)", 4660);
+        toUInt16.insert("QScriptValue(0, 0x10000)", 0);
+        toUInt16.insert("QScriptValue(0, 0x10001)", 1);
+        toUInt16.insert("QScriptValue(0, qSNaN())", 0);
+        toUInt16.insert("QScriptValue(0, qQNaN())", 0);
+        toUInt16.insert("QScriptValue(0, qInf())", 0);
+        toUInt16.insert("QScriptValue(0, -qInf())", 0);
+        toUInt16.insert("QScriptValue(0, \"NaN\")", 0);
+        toUInt16.insert("QScriptValue(0, \"Infinity\")", 0);
+        toUInt16.insert("QScriptValue(0, \"-Infinity\")", 0);
+        toUInt16.insert("QScriptValue(0, \"ciao\")", 0);
+        toUInt16.insert("QScriptValue(0, QString::fromLatin1(\"ciao\"))", 0);
+        toUInt16.insert("QScriptValue(0, QString(\"\"))", 0);
+        toUInt16.insert("QScriptValue(0, QString())", 0);
+        toUInt16.insert("QScriptValue(0, QString(\"0\"))", 0);
+        toUInt16.insert("QScriptValue(0, QString(\"123\"))", 123);
+        toUInt16.insert("QScriptValue(0, QString(\"12.3\"))", 12);
+        toUInt16.insert("QScriptValue(engine, QScriptValue::UndefinedValue)", 0);
+        toUInt16.insert("QScriptValue(engine, QScriptValue::NullValue)", 0);
+        toUInt16.insert("QScriptValue(engine, true)", 1);
+        toUInt16.insert("QScriptValue(engine, false)", 0);
+        toUInt16.insert("QScriptValue(engine, int(122))", 122);
+        toUInt16.insert("QScriptValue(engine, uint(124))", 124);
+        toUInt16.insert("QScriptValue(engine, 0)", 0);
+        toUInt16.insert("QScriptValue(engine, 0.0)", 0);
+        toUInt16.insert("QScriptValue(engine, 123.0)", 123);
+        toUInt16.insert("QScriptValue(engine, 6.37e-8)", 0);
+        toUInt16.insert("QScriptValue(engine, -6.37e-8)", 0);
+        toUInt16.insert("QScriptValue(engine, 0x43211234)", 4660);
+        toUInt16.insert("QScriptValue(engine, 0x10000)", 0);
+        toUInt16.insert("QScriptValue(engine, 0x10001)", 1);
+        toUInt16.insert("QScriptValue(engine, qSNaN())", 0);
+        toUInt16.insert("QScriptValue(engine, qQNaN())", 0);
+        toUInt16.insert("QScriptValue(engine, qInf())", 0);
+        toUInt16.insert("QScriptValue(engine, -qInf())", 0);
+        toUInt16.insert("QScriptValue(engine, \"NaN\")", 0);
+        toUInt16.insert("QScriptValue(engine, \"Infinity\")", 0);
+        toUInt16.insert("QScriptValue(engine, \"-Infinity\")", 0);
+        toUInt16.insert("QScriptValue(engine, \"ciao\")", 0);
+        toUInt16.insert("QScriptValue(engine, QString::fromLatin1(\"ciao\"))", 0);
+        toUInt16.insert("QScriptValue(engine, QString(\"\"))", 0);
+        toUInt16.insert("QScriptValue(engine, QString())", 0);
+        toUInt16.insert("QScriptValue(engine, QString(\"0\"))", 0);
+        toUInt16.insert("QScriptValue(engine, QString(\"123\"))", 123);
+        toUInt16.insert("QScriptValue(engine, QString(\"1.23\"))", 1);
+        toUInt16.insert("engine->evaluate(\"[]\")", 0);
+        toUInt16.insert("engine->evaluate(\"{}\")", 0);
+        toUInt16.insert("engine->evaluate(\"Object.prototype\")", 0);
+        toUInt16.insert("engine->evaluate(\"Date.prototype\")", 0);
+        toUInt16.insert("engine->evaluate(\"Array.prototype\")", 0);
+        toUInt16.insert("engine->evaluate(\"Function.prototype\")", 0);
+        toUInt16.insert("engine->evaluate(\"Error.prototype\")", 0);
+        toUInt16.insert("engine->evaluate(\"Object\")", 0);
+        toUInt16.insert("engine->evaluate(\"Array\")", 0);
+        toUInt16.insert("engine->evaluate(\"Number\")", 0);
+        toUInt16.insert("engine->evaluate(\"Function\")", 0);
+        toUInt16.insert("engine->evaluate(\"(function() { return 1; })\")", 0);
+        toUInt16.insert("engine->evaluate(\"(function() { return 'ciao'; })\")", 0);
+        toUInt16.insert("engine->evaluate(\"(function() { throw new Error('foo'); })\")", 0);
+        toUInt16.insert("engine->evaluate(\"/foo/\")", 0);
+        toUInt16.insert("engine->evaluate(\"new Object()\")", 0);
+        toUInt16.insert("engine->evaluate(\"new Array()\")", 0);
+        toUInt16.insert("engine->evaluate(\"new Error()\")", 0);
+        toUInt16.insert("engine->evaluate(\"a = new Object(); a.foo = 22; a.foo\")", 22);
+        toUInt16.insert("engine->evaluate(\"Undefined\")", 0);
+        toUInt16.insert("engine->evaluate(\"Null\")", 0);
+        toUInt16.insert("engine->evaluate(\"True\")", 0);
+        toUInt16.insert("engine->evaluate(\"False\")", 0);
+        toUInt16.insert("engine->evaluate(\"undefined\")", 0);
+        toUInt16.insert("engine->evaluate(\"null\")", 0);
+        toUInt16.insert("engine->evaluate(\"true\")", 1);
+        toUInt16.insert("engine->evaluate(\"false\")", 0);
+        toUInt16.insert("engine->evaluate(\"122\")", 122);
+        toUInt16.insert("engine->evaluate(\"124\")", 124);
+        toUInt16.insert("engine->evaluate(\"0\")", 0);
+        toUInt16.insert("engine->evaluate(\"0.0\")", 0);
+        toUInt16.insert("engine->evaluate(\"123.0\")", 123);
+        toUInt16.insert("engine->evaluate(\"6.37e-8\")", 0);
+        toUInt16.insert("engine->evaluate(\"-6.37e-8\")", 0);
+        toUInt16.insert("engine->evaluate(\"0x43211234\")", 4660);
+        toUInt16.insert("engine->evaluate(\"0x10000\")", 0);
+        toUInt16.insert("engine->evaluate(\"0x10001\")", 1);
+        toUInt16.insert("engine->evaluate(\"NaN\")", 0);
+        toUInt16.insert("engine->evaluate(\"Infinity\")", 0);
+        toUInt16.insert("engine->evaluate(\"-Infinity\")", 0);
+        toUInt16.insert("engine->evaluate(\"'ciao'\")", 0);
+        toUInt16.insert("engine->evaluate(\"''\")", 0);
+        toUInt16.insert("engine->evaluate(\"'0'\")", 0);
+        toUInt16.insert("engine->evaluate(\"'123'\")", 123);
+        toUInt16.insert("engine->evaluate(\"'12.4'\")", 12);
+        toUInt16.insert("engine->nullValue()", 0);
+        toUInt16.insert("engine->undefinedValue()", 0);
+    }
+    newRow(expr) << toUInt16.value(expr);
+}
+
+void tst_QScriptValue::toUInt16_test(const char*, const QScriptValue& value)
+{
+    QFETCH(quint16, expected);
+    QCOMPARE(value.toUInt16(), expected);
+    QCOMPARE(value.toUInt16(), expected);
+}
+
+DEFINE_TEST_FUNCTION(toUInt16)
index 1ce238fd7ac1ef5c717848e4729af923c12ad190..5af338369d06f5db4190161aab0c2f823c248928 100644 (file)
@@ -1,12 +1,3 @@
-isEmpty(OUTPUT_DIR) {
-    CONFIG(debug, debug|release) {
-        OUTPUT_DIR=$$PWD/WebKitBuild/Debug
-    } else { # Release
-        OUTPUT_DIR=$$PWD/WebKitBuild/Release
-    }
-}
-
-
 QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
 QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR
 mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) {
 QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR
 QMAKE_LIBDIR = $$OUTPUT_DIR/lib $$QMAKE_LIBDIR
 mac:!static:contains(QT_CONFIG, qt_framework):!CONFIG(webkit_no_framework) {
index 6e5edb1e43304350eea3acfc7bd4c02d7e7620c3..7c3f590c5c9c80abc609b4d2400c62ca1294b4e7 100644 (file)
@@ -1,3 +1,4 @@
 TEMPLATE = subdirs
 SUBDIRS =   qscriptengine \
 TEMPLATE = subdirs
 SUBDIRS =   qscriptengine \
-            qscriptvalue
+            qscriptvalue \
+            qscriptstring
index ce814b2adcca34f117e3777a29f70bd648ac9f1f..20ad8c1ef2a8ac72281d3efb2964f246a224d206 100644 (file)
 #include "config.h"
 #include "ArrayPrototype.h"
 
 #include "config.h"
 #include "ArrayPrototype.h"
 
-#include "CodeBlock.h"
 #include "CachedCall.h"
 #include "CachedCall.h"
+#include "CodeBlock.h"
 #include "Interpreter.h"
 #include "JIT.h"
 #include "Interpreter.h"
 #include "JIT.h"
-#include "ObjectPrototype.h"
+#include "JSStringBuilder.h"
 #include "Lookup.h"
 #include "Lookup.h"
+#include "ObjectPrototype.h"
 #include "Operations.h"
 #include <algorithm>
 #include <wtf/Assertions.h>
 #include "Operations.h"
 #include <algorithm>
 #include <wtf/Assertions.h>
@@ -75,13 +76,21 @@ static inline bool isNumericCompareFunction(ExecState* exec, CallType callType,
 #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.
 #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.functionExecutable->jitCode(exec, callData.js.scopeChain);
-    CodeBlock& codeBlock = callData.js.functionExecutable->generatedBytecode();
+    CodeBlock* codeBlock = 0;
+#if ENABLE(INTERPRETER)
+    if (!exec->globalData().canUseJIT())
+        codeBlock = &callData.js.functionExecutable->bytecode(exec, callData.js.scopeChain);
+    else
+#endif
+    {
+        callData.js.functionExecutable->jitCode(exec, callData.js.scopeChain);
+        codeBlock = &callData.js.functionExecutable->generatedBytecode();
+    }
 #else
 #else
-    CodeBlock& codeBlock = callData.js.functionExecutable->bytecode(exec, callData.js.scopeChain);
+    CodeBlock* codeBlock = &callData.js.functionExecutable->bytecode(exec, callData.js.scopeChain);
 #endif
 
 #endif
 
-    return codeBlock.isNumericCompareFunction();
+    return codeBlock->isNumericCompareFunction();
 }
 
 // ------------------------------ ArrayPrototype ----------------------------
 }
 
 // ------------------------------ ArrayPrototype ----------------------------
@@ -155,9 +164,9 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
     JSArray* thisObj = asArray(thisValue);
     
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
     JSArray* thisObj = asArray(thisValue);
     
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
-    if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) {
-        if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
-            return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
+        if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
+            return throwError(exec, RangeError, "Maximum call stack size exceeded.");    
     }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
@@ -182,8 +191,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
         totalSize += str.size();
         
         if (!strBuffer.data()) {
         totalSize += str.size();
         
         if (!strBuffer.data()) {
-            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
-            exec->setException(error);
+            throwOutOfMemoryError(exec);
         }
         
         if (exec->hadException())
         }
         
         if (exec->hadException())
@@ -195,13 +203,13 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
     Vector<UChar> buffer;
     buffer.reserveCapacity(totalSize);
     if (!buffer.data())
     Vector<UChar> buffer;
     buffer.reserveCapacity(totalSize);
     if (!buffer.data())
-        return throwError(exec, GeneralError, "Out of memory");
+        return throwOutOfMemoryError(exec);
         
     for (unsigned i = 0; i < length; i++) {
         if (i)
             buffer.append(',');
         if (RefPtr<UString::Rep> rep = strBuffer[i])
         
     for (unsigned i = 0; i < length; i++) {
         if (i)
             buffer.append(',');
         if (RefPtr<UString::Rep> rep = strBuffer[i])
-            buffer.append(rep->data(), rep->size());
+            buffer.append(rep->characters(), rep->length());
     }
     ASSERT(buffer.size() == totalSize);
     return jsString(exec, UString::adopt(buffer));
     }
     ASSERT(buffer.size() == totalSize);
     return jsString(exec, UString::adopt(buffer));
@@ -214,51 +222,37 @@ JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, J
     JSObject* thisObj = asArray(thisValue);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
     JSObject* thisObj = asArray(thisValue);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
-    if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) {
-        if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
-            return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
+        if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
+            return throwError(exec, RangeError, "Maximum call stack size exceeded.");    
     }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     if (alreadyVisited)
         return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
 
     }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     if (alreadyVisited)
         return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
 
-    Vector<UChar, 256> strBuffer;
+    JSStringBuilder strBuffer;
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     for (unsigned k = 0; k < length; k++) {
         if (k >= 1)
             strBuffer.append(',');
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
     for (unsigned k = 0; k < length; k++) {
         if (k >= 1)
             strBuffer.append(',');
-        if (!strBuffer.data()) {
-            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
-            exec->setException(error);
-            break;
-        }
 
         JSValue element = thisObj->get(exec, k);
 
         JSValue element = thisObj->get(exec, k);
-        if (element.isUndefinedOrNull())
-            continue;
-
-        JSObject* o = element.toObject(exec);
-        JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
-        UString str;
-        CallData callData;
-        CallType callType = conversionFunction.getCallData(callData);
-        if (callType != CallTypeNone)
-            str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec);
-        else
-            str = element.toString(exec);
-        strBuffer.append(str.data(), str.size());
-
-        if (!strBuffer.data()) {
-            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
-            exec->setException(error);
+        if (!element.isUndefinedOrNull()) {
+            JSObject* o = element.toObject(exec);
+            JSValue conversionFunction = o->get(exec, exec->propertyNames().toLocaleString);
+            UString str;
+            CallData callData;
+            CallType callType = conversionFunction.getCallData(callData);
+            if (callType != CallTypeNone)
+                str = call(exec, conversionFunction, callType, callData, element, exec->emptyList()).toString(exec);
+            else
+                str = element.toString(exec);
+            strBuffer.append(str);
         }
         }
-
-        if (exec->hadException())
-            break;
     }
     arrayVisitedElements.remove(thisObj);
     }
     arrayVisitedElements.remove(thisObj);
-    return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+    return strBuffer.build(exec);
 }
 
 JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 }
 
 JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -266,47 +260,53 @@ JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thi
     JSObject* thisObj = thisValue.toThisObject(exec);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
     JSObject* thisObj = thisValue.toThisObject(exec);
 
     HashSet<JSObject*>& arrayVisitedElements = exec->globalData().arrayVisitedElements;
-    if (arrayVisitedElements.size() >= MaxSecondaryThreadReentryDepth) {
-        if (!isMainThread() || arrayVisitedElements.size() >= MaxMainThreadReentryDepth)
-            return throwError(exec, RangeError, "Maximum call stack size exceeded.");
+    if (arrayVisitedElements.size() >= MaxSmallThreadReentryDepth) {
+        if (arrayVisitedElements.size() >= exec->globalData().maxReentryDepth)
+            return throwError(exec, RangeError, "Maximum call stack size exceeded.");    
     }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     if (alreadyVisited)
         return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
 
     }
 
     bool alreadyVisited = !arrayVisitedElements.add(thisObj).second;
     if (alreadyVisited)
         return jsEmptyString(exec); // return an empty string, avoding infinite recursion.
 
-    Vector<UChar, 256> strBuffer;
+    JSStringBuilder strBuffer;
 
 
-    UChar comma = ',';
-    UString separator = args.at(0).isUndefined() ? UString(&comma, 1) : args.at(0).toString(exec);
+    UString separator;
+    if (!args.at(0).isUndefined())
+        separator = args.at(0).toString(exec);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
 
     unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
-    for (unsigned k = 0; k < length; k++) {
-        if (k >= 1)
-            strBuffer.append(separator.data(), separator.size());
-        if (!strBuffer.data()) {
-            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
-            exec->setException(error);
-            break;
+    unsigned k = 0;
+    if (isJSArray(&exec->globalData(), thisObj)) {
+        JSArray* array = asArray(thisObj);
+        for (; k < length; k++) {
+            if (!array->canGetIndex(k))
+                break;
+            if (k >= 1) {
+                if (separator.isNull())
+                    strBuffer.append(',');
+                else
+                    strBuffer.append(separator);
+            }
+            JSValue element = array->getIndex(k);
+            if (!element.isUndefinedOrNull())
+                strBuffer.append(element.toString(exec));
         }
         }
-
-        JSValue element = thisObj->get(exec, k);
-        if (element.isUndefinedOrNull())
-            continue;
-
-        UString str = element.toString(exec);
-        strBuffer.append(str.data(), str.size());
-
-        if (!strBuffer.data()) {
-            JSObject* error = Error::create(exec, GeneralError, "Out of memory");
-            exec->setException(error);
+    }
+    for (; k < length; k++) {
+        if (k >= 1) {
+            if (separator.isNull())
+                strBuffer.append(',');
+            else
+                strBuffer.append(separator);
         }
 
         }
 
-        if (exec->hadException())
-            break;
+        JSValue element = thisObj->get(exec, k);
+        if (!element.isUndefinedOrNull())
+            strBuffer.append(element.toString(exec));
     }
     arrayVisitedElements.remove(thisObj);
     }
     arrayVisitedElements.remove(thisObj);
-    return jsString(exec, UString(strBuffer.data(), strBuffer.data() ? strBuffer.size() : 0));
+    return strBuffer.build(exec);
 }
 
 JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 }
 
 JSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -531,14 +531,19 @@ JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue t
     // 15.4.4.12
     JSArray* resObj = constructEmptyArray(exec);
     JSValue result = resObj;
     // 15.4.4.12
     JSArray* resObj = constructEmptyArray(exec);
     JSValue result = resObj;
-    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+
+    // FIXME: Firefox returns an empty array.
     if (!args.size())
         return jsUndefined();
     if (!args.size())
         return jsUndefined();
-    int begin = args.at(0).toUInt32(exec);
-    if (begin < 0)
-        begin = std::max<int>(begin + length, 0);
-    else
-        begin = std::min<int>(begin, length);
+
+    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
+    double relativeBegin = args.at(0).toInteger(exec);
+    unsigned begin;
+    if (relativeBegin < 0) {
+        relativeBegin += length;
+        begin = (relativeBegin < 0) ? 0 : static_cast<unsigned>(relativeBegin);
+    } else
+        begin = std::min<unsigned>(static_cast<unsigned>(relativeBegin), length);
 
     unsigned deleteCount;
     if (args.size() > 1)
 
     unsigned deleteCount;
     if (args.size() > 1)
@@ -564,7 +569,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue t
             for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
                 thisObj->deleteProperty(exec, k - 1);
         } else {
             for (unsigned k = length; k > length - deleteCount + additionalArgs; --k)
                 thisObj->deleteProperty(exec, k - 1);
         } else {
-            for (unsigned k = length - deleteCount; (int)k > begin; --k) {
+            for (unsigned k = length - deleteCount; k > begin; --k) {
                 if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1))
                     thisObj->put(exec, k + additionalArgs - 1, obj);
                 else
                 if (JSValue obj = getProperty(exec, thisObj, k + deleteCount - 1))
                     thisObj->put(exec, k + additionalArgs - 1, obj);
                 else
diff --git a/runtime/CachedTranscendentalFunction.h b/runtime/CachedTranscendentalFunction.h
new file mode 100644 (file)
index 0000000..04f7f62
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 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 CachedTranscendentalFunction_h
+#define CachedTranscendentalFunction_h
+
+#include "JSValue.h"
+
+namespace JSC {
+
+extern const double NaN;
+
+typedef double (*TranscendentalFunctionPtr)(double);
+
+// CachedTranscendentalFunction provides a generic mechanism to cache results
+// for pure functions with the signature "double func(double)", and where NaN
+// maps to NaN.
+template<TranscendentalFunctionPtr orignalFunction>
+class CachedTranscendentalFunction {
+    struct CacheEntry {
+        double operand;
+        double result;
+    };
+
+public:
+    CachedTranscendentalFunction()
+        : m_cache(0)
+    {
+    }
+
+    ~CachedTranscendentalFunction()
+    {
+        if (m_cache)
+            fastFree(m_cache);
+    }
+
+    JSValue operator() (ExecState* exec, double operand)
+    {
+        if (UNLIKELY(!m_cache))
+            initialize();
+        CacheEntry* entry = &m_cache[hash(operand)];
+
+        if (entry->operand == operand)
+            return jsDoubleNumber(exec, entry->result);
+        double result = orignalFunction(operand);
+        entry->operand = operand;
+        entry->result = result;
+        return jsDoubleNumber(exec, result);
+    }
+
+private:
+    void initialize()
+    {
+        // Lazily allocate the table, populate with NaN->NaN mapping.
+        m_cache = static_cast<CacheEntry*>(fastMalloc(s_cacheSize * sizeof(CacheEntry)));
+        for (unsigned x = 0; x < s_cacheSize; ++x) {
+            m_cache[x].operand = NaN;
+            m_cache[x].result = NaN;
+        }
+    }
+
+    static unsigned hash(double d)
+    {
+        union doubleAndUInt64 {
+            double d;
+            uint32_t is[2];
+        } u;
+        u.d = d;
+
+        unsigned x = u.is[0] ^ u.is[1];
+        x = (x >> 20) ^ (x >> 8);
+        return x & (s_cacheSize - 1);
+    }
+
+    static const unsigned s_cacheSize = 0x1000;
+    CacheEntry* m_cache;
+};
+
+}
+
+#endif // CachedTranscendentalFunction_h
index d252fb58180512669d206cd5c563aceea93992e0..05f2bb5628de669fcfa25492b079855d19ed2d58 100644 (file)
 #include <mach/thread_act.h>
 #include <mach/vm_map.h>
 
 #include <mach/thread_act.h>
 #include <mach/vm_map.h>
 
-#elif OS(SYMBIAN)
-#include <e32std.h>
-#include <e32cmn.h>
-#include <unistd.h>
-
 #elif OS(WINDOWS)
 
 #include <windows.h>
 #elif OS(WINDOWS)
 
 #include <windows.h>
@@ -109,11 +104,6 @@ const size_t ALLOCATIONS_PER_COLLECTION = 3600;
 // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
 #define MIN_ARRAY_SIZE (static_cast<size_t>(14))
 
 // a PIC branch in Mach-O binaries, see <rdar://problem/5971391>.
 #define MIN_ARRAY_SIZE (static_cast<size_t>(14))
 
-#if OS(SYMBIAN)
-const size_t MAX_NUM_BLOCKS = 256; // Max size of collector heap set to 16 MB
-static RHeap* userChunk = 0;
-#endif
-
 #if ENABLE(JSC_MULTIPLE_THREADS)
 
 #if OS(DARWIN)
 #if ENABLE(JSC_MULTIPLE_THREADS)
 
 #if OS(DARWIN)
@@ -144,31 +134,13 @@ Heap::Heap(JSGlobalData* globalData)
 #if ENABLE(JSC_MULTIPLE_THREADS)
     , m_registeredThreads(0)
     , m_currentThreadRegistrar(0)
 #if ENABLE(JSC_MULTIPLE_THREADS)
     , m_registeredThreads(0)
     , m_currentThreadRegistrar(0)
+#endif
+#if OS(SYMBIAN)
+    , m_blockallocator(JSCCOLLECTOR_VIRTUALMEM_RESERVATION, BLOCK_SIZE)
 #endif
     , m_globalData(globalData)
 {
     ASSERT(globalData);
 #endif
     , m_globalData(globalData)
 {
     ASSERT(globalData);
-    
-#if OS(SYMBIAN)
-    // Symbian OpenC supports mmap but currently not the MAP_ANON flag.
-    // Using fastMalloc() does not properly align blocks on 64k boundaries
-    // and previous implementation was flawed/incomplete.
-    // UserHeap::ChunkHeap allows allocation of continuous memory and specification
-    // of alignment value for (symbian) cells within that heap.
-    //
-    // Clarification and mapping of terminology:
-    // RHeap (created by UserHeap::ChunkHeap below) is continuos memory chunk,
-    // which can dynamically grow up to 8 MB,
-    // that holds all CollectorBlocks of this session (static).
-    // Each symbian cell within RHeap maps to a 64kb aligned CollectorBlock.
-    // JSCell objects are maintained as usual within CollectorBlocks.
-    if (!userChunk) {
-        userChunk = UserHeap::ChunkHeap(0, 0, MAX_NUM_BLOCKS * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE);
-        if (!userChunk)
-            CRASH();
-    }
-#endif // OS(SYMBIAN)
-    
     memset(&m_heap, 0, sizeof(CollectorHeap));
     allocateBlock();
 }
     memset(&m_heap, 0, sizeof(CollectorHeap));
     allocateBlock();
 }
@@ -211,7 +183,9 @@ void Heap::destroy()
         t = next;
     }
 #endif
         t = next;
     }
 #endif
-
+#if OS(SYMBIAN)
+    m_blockallocator.destroy();
+#endif
     m_globalData = 0;
 }
 
     m_globalData = 0;
 }
 
@@ -221,15 +195,13 @@ NEVER_INLINE CollectorBlock* Heap::allocateBlock()
     vm_address_t address = 0;
     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 OS(SYMBIAN)
     vm_address_t address = 0;
     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 OS(SYMBIAN)
-    // Allocate a 64 kb aligned CollectorBlock
-    unsigned char* mask = reinterpret_cast<unsigned char*>(userChunk->Alloc(BLOCK_SIZE));
-    if (!mask)
+    void* address = m_blockallocator.alloc();  
+    if (!address)
         CRASH();
         CRASH();
-    uintptr_t address = reinterpret_cast<uintptr_t>(mask);
 #elif OS(WINCE)
     void* address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
 #elif OS(WINDOWS)
 #elif OS(WINCE)
     void* address = VirtualAlloc(NULL, BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
 #elif OS(WINDOWS)
-#if COMPILER(MINGW)
+#if COMPILER(MINGW) && !COMPILER(MINGW64)
     void* address = __mingw_aligned_malloc(BLOCK_SIZE, BLOCK_SIZE);
 #else
     void* address = _aligned_malloc(BLOCK_SIZE, BLOCK_SIZE);
     void* address = __mingw_aligned_malloc(BLOCK_SIZE, BLOCK_SIZE);
 #else
     void* address = _aligned_malloc(BLOCK_SIZE, BLOCK_SIZE);
@@ -316,11 +288,11 @@ NEVER_INLINE void Heap::freeBlockPtr(CollectorBlock* block)
 #if OS(DARWIN)    
     vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE);
 #elif OS(SYMBIAN)
 #if OS(DARWIN)    
     vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(block), BLOCK_SIZE);
 #elif OS(SYMBIAN)
-    userChunk->Free(reinterpret_cast<TAny*>(block));
+    m_blockallocator.free(reinterpret_cast<void*>(block));
 #elif OS(WINCE)
     VirtualFree(block, 0, MEM_RELEASE);
 #elif OS(WINDOWS)
 #elif OS(WINCE)
     VirtualFree(block, 0, MEM_RELEASE);
 #elif OS(WINDOWS)
-#if COMPILER(MINGW)
+#if COMPILER(MINGW) && !COMPILER(MINGW64)
     __mingw_aligned_free(block);
 #else
     _aligned_free(block);
     __mingw_aligned_free(block);
 #else
     _aligned_free(block);
@@ -477,7 +449,7 @@ void Heap::shrinkBlocks(size_t neededBlocks)
 }
 
 #if OS(WINCE)
 }
 
 #if OS(WINCE)
-void* g_stackBase = 0;
+JS_EXPORTDATA void* g_stackBase = 0;
 
 inline bool isPageWritable(void* page)
 {
 
 inline bool isPageWritable(void* page)
 {
@@ -574,10 +546,6 @@ static inline void* currentThreadStackBase()
         MOV pTib, EAX
     }
     return static_cast<void*>(pTib->StackBase);
         MOV pTib, EAX
     }
     return static_cast<void*>(pTib->StackBase);
-#elif OS(WINDOWS) && CPU(X86_64) && COMPILER(MSVC)
-    // FIXME: why only for MSVC?
-    PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
-    return reinterpret_cast<void*>(pTib->StackBase);
 #elif OS(WINDOWS) && CPU(X86) && COMPILER(GCC)
     // offset 0x18 from the FS segment register gives a pointer to
     // the thread information block for the current thread
 #elif OS(WINDOWS) && CPU(X86) && COMPILER(GCC)
     // offset 0x18 from the FS segment register gives a pointer to
     // the thread information block for the current thread
@@ -586,7 +554,12 @@ static inline void* currentThreadStackBase()
           : "=r" (pTib)
         );
     return static_cast<void*>(pTib->StackBase);
           : "=r" (pTib)
         );
     return static_cast<void*>(pTib->StackBase);
+#elif OS(WINDOWS) && CPU(X86_64)
+    PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb());
+    return reinterpret_cast<void*>(pTib->StackBase);
 #elif OS(QNX)
 #elif OS(QNX)
+    AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+    MutexLocker locker(mutex);
     return currentThreadStackBaseQNX();
 #elif OS(SOLARIS)
     stack_t s;
     return currentThreadStackBaseQNX();
 #elif OS(SOLARIS)
     stack_t s;
@@ -598,19 +571,17 @@ static inline void* currentThreadStackBase()
     pthread_stackseg_np(thread, &stack);
     return stack.ss_sp;
 #elif OS(SYMBIAN)
     pthread_stackseg_np(thread, &stack);
     return stack.ss_sp;
 #elif OS(SYMBIAN)
-    static void* stackBase = 0;
-    if (stackBase == 0) {
-        TThreadStackInfo info;
-        RThread thread;
-        thread.StackInfo(info);
-        stackBase = (void*)info.iBase;
-    }
-    return (void*)stackBase;
+    TThreadStackInfo info;
+    RThread thread;
+    thread.StackInfo(info);
+    return (void*)info.iBase;
 #elif OS(HAIKU)
     thread_info threadInfo;
     get_thread_info(find_thread(NULL), &threadInfo);
     return threadInfo.stack_end;
 #elif OS(UNIX)
 #elif OS(HAIKU)
     thread_info threadInfo;
     get_thread_info(find_thread(NULL), &threadInfo);
     return threadInfo.stack_end;
 #elif OS(UNIX)
+    AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+    MutexLocker locker(mutex);
     static void* stackBase = 0;
     static size_t stackSize = 0;
     static pthread_t stackThread;
     static void* stackBase = 0;
     static size_t stackSize = 0;
     static pthread_t stackThread;
@@ -633,6 +604,8 @@ static inline void* currentThreadStackBase()
     }
     return static_cast<char*>(stackBase) + stackSize;
 #elif OS(WINCE)
     }
     return static_cast<char*>(stackBase) + stackSize;
 #elif OS(WINCE)
+    AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+    MutexLocker locker(mutex);
     if (g_stackBase)
         return g_stackBase;
     else {
     if (g_stackBase)
         return g_stackBase;
     else {
@@ -667,7 +640,7 @@ void Heap::makeUsableFromMultipleThreads()
 
 void Heap::registerThread()
 {
 
 void Heap::registerThread()
 {
-    ASSERT(!m_globalData->mainThreadOnly || isMainThread() || pthread_main_np());
+    ASSERT(!m_globalData->exclusiveThread || m_globalData->exclusiveThread == currentThread());
 
     if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
         return;
 
     if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
         return;
@@ -1001,7 +974,7 @@ void Heap::markStackObjectsConservatively(MarkStack& markStack)
 void Heap::protect(JSValue k)
 {
     ASSERT(k);
 void Heap::protect(JSValue k)
 {
     ASSERT(k);
-    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
+    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance());
 
     if (!k.isCell())
         return;
 
     if (!k.isCell())
         return;
@@ -1009,15 +982,15 @@ void Heap::protect(JSValue k)
     m_protectedValues.add(k.asCell());
 }
 
     m_protectedValues.add(k.asCell());
 }
 
-void Heap::unprotect(JSValue k)
+bool Heap::unprotect(JSValue k)
 {
     ASSERT(k);
 {
     ASSERT(k);
-    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
+    ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance());
 
     if (!k.isCell())
 
     if (!k.isCell())
-        return;
+        return false;
 
 
-    m_protectedValues.remove(k.asCell());
+    return m_protectedValues.remove(k.asCell());
 }
 
 void Heap::markProtectedObjects(MarkStack& markStack)
 }
 
 void Heap::markProtectedObjects(MarkStack& markStack)
@@ -1093,7 +1066,7 @@ void Heap::sweep()
 void Heap::markRoots()
 {
 #ifndef NDEBUG
 void Heap::markRoots()
 {
 #ifndef NDEBUG
-    if (m_globalData->isSharedInstance) {
+    if (m_globalData->isSharedInstance()) {
         ASSERT(JSLock::lockCount() > 0);
         ASSERT(JSLock::currentThreadIsHoldingLock());
     }
         ASSERT(JSLock::lockCount() > 0);
         ASSERT(JSLock::currentThreadIsHoldingLock());
     }
@@ -1200,12 +1173,13 @@ static const char* typeName(JSCell* cell)
         return "number";
 #endif
     if (cell->isGetterSetter())
         return "number";
 #endif
     if (cell->isGetterSetter())
-        return "gettersetter";
+        return "Getter-Setter";
     if (cell->isAPIValueWrapper())
     if (cell->isAPIValueWrapper())
-        return "value wrapper";
+        return "API wrapper";
     if (cell->isPropertyNameIterator())
     if (cell->isPropertyNameIterator())
-        return "for-in iterator";
-    ASSERT(cell->isObject());
+        return "For-in iterator";
+    if (!cell->isObject())
+        return "[empty cell]";
     const ClassInfo* info = cell->classInfo();
     return info ? info->className : "Object";
 }
     const ClassInfo* info = cell->classInfo();
     return info ? info->className : "Object";
 }
@@ -1221,6 +1195,18 @@ HashCountedSet<const char*>* Heap::protectedObjectTypeCounts()
     return counts;
 }
 
     return counts;
 }
 
+HashCountedSet<const char*>* Heap::objectTypeCounts()
+{
+    HashCountedSet<const char*>* counts = new HashCountedSet<const char*>;
+
+    LiveObjectIterator it = primaryHeapBegin();
+    LiveObjectIterator heapEnd = primaryHeapEnd();
+    for ( ; it != heapEnd; ++it)
+        counts->add(typeName(*it));
+
+    return counts;
+}
+
 bool Heap::isBusy()
 {
     return m_heap.operationInProgress != NoOperation;
 bool Heap::isBusy()
 {
     return m_heap.operationInProgress != NoOperation;
index 9d73e5eb92441fec2ebd846eb3e8bf0c57861eb7..6599652035902be5637d23b2686cbee9bd3703c6 100644 (file)
 #include <pthread.h>
 #endif
 
 #include <pthread.h>
 #endif
 
+#if OS(SYMBIAN)
+#include <wtf/symbian/BlockAllocatorSymbian.h>
+#endif
+
 #define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= CELL_SIZE, class_fits_in_cell)
 
 namespace JSC {
 #define ASSERT_CLASS_FITS_IN_CELL(class) COMPILE_ASSERT(sizeof(class) <= CELL_SIZE, class_fits_in_cell)
 
 namespace JSC {
@@ -91,7 +95,9 @@ namespace JSC {
         Statistics statistics() const;
 
         void protect(JSValue);
         Statistics statistics() const;
 
         void protect(JSValue);
-        void unprotect(JSValue);
+        // Returns true if the value is no longer protected by any protect pointers
+        // (though it may still be alive due to heap/stack references).
+        bool unprotect(JSValue);
 
         static Heap* heap(JSValue); // 0 for immediate values
         static Heap* heap(JSCell*);
 
         static Heap* heap(JSValue); // 0 for immediate values
         static Heap* heap(JSCell*);
@@ -100,6 +106,7 @@ namespace JSC {
         size_t protectedObjectCount();
         size_t protectedGlobalObjectCount();
         HashCountedSet<const char*>* protectedObjectTypeCounts();
         size_t protectedObjectCount();
         size_t protectedGlobalObjectCount();
         HashCountedSet<const char*>* protectedObjectTypeCounts();
+        HashCountedSet<const char*>* objectTypeCounts();
 
         void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
 
 
         void registerThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
 
@@ -167,6 +174,11 @@ namespace JSC {
         pthread_key_t m_currentThreadRegistrar;
 #endif
 
         pthread_key_t m_currentThreadRegistrar;
 #endif
 
+#if OS(SYMBIAN)
+        // Allocates collector blocks with correct alignment
+        WTF::AlignedBlockAllocator m_blockallocator; 
+#endif
+        
         JSGlobalData* m_globalData;
     };
 
         JSGlobalData* m_globalData;
     };
 
index e4f2f91acd11207360e9a18295270013f0a4fcc7..be6f3c94baf42aa2de0cb81eb8644abe56e5a9e2 100644 (file)
@@ -38,7 +38,7 @@ namespace JSC {
     
     protected:
         CollectorHeapIterator(CollectorHeap&, size_t startBlock, size_t startCell);
     
     protected:
         CollectorHeapIterator(CollectorHeap&, size_t startBlock, size_t startCell);
-        void advance(size_t cellsPerBlock);
+        void advance(size_t max);
 
         CollectorHeap& m_heap;
         size_t m_block;
 
         CollectorHeap& m_heap;
         size_t m_block;
@@ -80,10 +80,12 @@ namespace JSC {
         return reinterpret_cast<JSCell*>(m_heap.blocks[m_block]->cells + m_cell);
     }
     
         return reinterpret_cast<JSCell*>(m_heap.blocks[m_block]->cells + m_cell);
     }
     
-    inline void CollectorHeapIterator::advance(size_t cellsPerBlock)
+    // Iterators advance up to the next-to-last -- and not the last -- cell in a
+    // block, since the last cell is a dummy sentinel.
+    inline void CollectorHeapIterator::advance(size_t max)
     {
         ++m_cell;
     {
         ++m_cell;
-        if (m_cell == cellsPerBlock) {
+        if (m_cell == max) {
             m_cell = 0;
             ++m_block;
         }
             m_cell = 0;
             ++m_block;
         }
@@ -97,14 +99,12 @@ namespace JSC {
 
     inline LiveObjectIterator& LiveObjectIterator::operator++()
     {
 
     inline LiveObjectIterator& LiveObjectIterator::operator++()
     {
-        if (m_block < m_heap.nextBlock || m_cell < m_heap.nextCell) {
-            advance(HeapConstants::cellsPerBlock);
+        advance(HeapConstants::cellsPerBlock - 1);
+        if (m_block < m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell < m_heap.nextCell))
             return *this;
             return *this;
-        }
 
 
-        do {
-            advance(HeapConstants::cellsPerBlock);
-        } while (m_block < m_heap.usedBlocks && !m_heap.blocks[m_block]->marked.get(m_cell));
+        while (m_block < m_heap.usedBlocks && !m_heap.blocks[m_block]->marked.get(m_cell))
+            advance(HeapConstants::cellsPerBlock - 1);
         return *this;
     }
 
         return *this;
     }
 
@@ -117,7 +117,7 @@ namespace JSC {
     inline DeadObjectIterator& DeadObjectIterator::operator++()
     {
         do {
     inline DeadObjectIterator& DeadObjectIterator::operator++()
     {
         do {
-            advance(HeapConstants::cellsPerBlock);
+            advance(HeapConstants::cellsPerBlock - 1);
             ASSERT(m_block > m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell >= m_heap.nextCell));
         } while (m_block < m_heap.usedBlocks && m_heap.blocks[m_block]->marked.get(m_cell));
         return *this;
             ASSERT(m_block > m_heap.nextBlock || (m_block == m_heap.nextBlock && m_cell >= m_heap.nextCell));
         } while (m_block < m_heap.usedBlocks && m_heap.blocks[m_block]->marked.get(m_cell));
         return *this;
@@ -131,7 +131,7 @@ namespace JSC {
 
     inline ObjectIterator& ObjectIterator::operator++()
     {
 
     inline ObjectIterator& ObjectIterator::operator++()
     {
-        advance(HeapConstants::cellsPerBlock);
+        advance(HeapConstants::cellsPerBlock - 1);
         return *this;
     }
 
         return *this;
     }
 
index 2f88df95d8cd6d118dab96598eedb6dad7dd3285..9af5171a11defb9d415d04a27fef3046345245f1 100644 (file)
@@ -29,6 +29,7 @@
 #include "Interpreter.h"
 #include "Parser.h"
 #include "Debugger.h"
 #include "Interpreter.h"
 #include "Parser.h"
 #include "Debugger.h"
+#include "WTFThreadData.h"
 #include <stdio.h>
 
 namespace JSC {
 #include <stdio.h>
 
 namespace JSC {
@@ -36,7 +37,7 @@ namespace JSC {
 Completion checkSyntax(ExecState* exec, const SourceCode& source)
 {
     JSLock lock(exec);
 Completion checkSyntax(ExecState* exec, const SourceCode& source)
 {
     JSLock lock(exec);
-    ASSERT(exec->globalData().identifierTable == currentIdentifierTable());
+    ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
 
     RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
     JSObject* error = program->checkSyntax(exec);
 
     RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
     JSObject* error = program->checkSyntax(exec);
@@ -49,7 +50,7 @@ Completion checkSyntax(ExecState* exec, const SourceCode& source)
 Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue)
 {
     JSLock lock(exec);
 Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& source, JSValue thisValue)
 {
     JSLock lock(exec);
-    ASSERT(exec->globalData().identifierTable == currentIdentifierTable());
+    ASSERT(exec->globalData().identifierTable == wtfThreadData().currentIdentifierTable());
 
     RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
     JSObject* error = program->compile(exec, scopeChain.node());
 
     RefPtr<ProgramExecutable> program = ProgramExecutable::create(exec, source);
     JSObject* error = program->compile(exec, scopeChain.node());
@@ -62,9 +63,10 @@ Completion evaluate(ExecState* exec, ScopeChain& scopeChain, const SourceCode& s
     JSValue result = exec->interpreter()->execute(program.get(), exec, scopeChain.node(), thisObj, &exception);
 
     if (exception) {
     JSValue result = exec->interpreter()->execute(program.get(), exec, scopeChain.node(), thisObj, &exception);
 
     if (exception) {
-        if (exception.isObject() && asObject(exception)->isWatchdogException())
-            return Completion(Interrupted, exception);
-        return Completion(Throw, exception);
+        ComplType exceptionType = Throw;
+        if (exception.isObject())
+            exceptionType = asObject(exception)->exceptionType();
+        return Completion(exceptionType, exception);
     }
     return Completion(Normal, result);
 }
     }
     return Completion(Normal, result);
 }
index 41c9a642f286e037fea5e7f66a428bf8693c9f99..63b315e18f639dd84f5ebca8a5dea077f432e320 100644 (file)
@@ -31,7 +31,7 @@ namespace JSC {
     class ScopeChain;
     class SourceCode;
 
     class ScopeChain;
     class SourceCode;
 
-    enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted };
+    enum ComplType { Normal, Break, Continue, ReturnValue, Throw, Interrupted, Terminated };
 
     /*
      * Completion objects are used to convey the return status and value
 
     /*
      * Completion objects are used to convey the return status and value
index 2e476b3b756be2515a43d613bf34a614997dbb86..ab95d0668d16f75afababea2872f155fbaeef276 100644 (file)
@@ -28,6 +28,7 @@
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
+#include "JSStringBuilder.h"
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
 #include <math.h>
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
 #include <math.h>
@@ -137,7 +138,7 @@ static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const
     DateConversionBuffer time;
     formatDate(ts, date);
     formatTime(ts, time);
     DateConversionBuffer time;
     formatDate(ts, date);
     formatTime(ts, time);
-    return jsNontrivialString(exec, makeString(date, " ", time));
+    return jsMakeNontrivialString(exec, date, " ", time);
 }
 
 CallType DateConstructor::getCallData(CallData& callData)
 }
 
 CallType DateConstructor::getCallData(CallData& callData)
@@ -177,7 +178,7 @@ static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const
     t.minute = args.at(4).toInt32(exec);
     t.second = args.at(5).toInt32(exec);
     double ms = (n >= 7) ? args.at(6).toNumber(exec) : 0;
     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(exec, t, ms, true));
+    return jsNumber(exec, timeClip(gregorianDateTimeToMS(exec, t, ms, true)));
 }
 
 } // namespace JSC
 }
 
 } // namespace JSC
index f129407f7b1da41ba0b5ab46289dfe80ddee5935..70dbaa0306362cbb5d698336be7877f7f189ce48 100644 (file)
@@ -56,7 +56,7 @@ double parseDate(ExecState* exec, const UString &date)
 {
     if (date == exec->globalData().cachedDateString)
         return exec->globalData().cachedDateStringValue;
 {
     if (date == exec->globalData().cachedDateString)
         return exec->globalData().cachedDateStringValue;
-    double value = parseDateFromNullTerminatedCharacters(exec, date.UTF8String().c_str());
+    double value = parseDateFromNullTerminatedCharacters(exec, date.UTF8String().data());
     exec->globalData().cachedDateString = date;
     exec->globalData().cachedDateStringValue = value;
     return value;
     exec->globalData().cachedDateString = date;
     exec->globalData().cachedDateStringValue = value;
     return value;
index c0df7e96cfbc712ead62a764f96bbad83278dbc9..4ff3e7e55262cd63d655c38b800d4fe034be4354 100644 (file)
 #include "DatePrototype.h"
 
 #include "DateConversion.h"
 #include "DatePrototype.h"
 
 #include "DateConversion.h"
+#include "DateInstance.h"
 #include "Error.h"
 #include "JSString.h"
 #include "Error.h"
 #include "JSString.h"
+#include "JSStringBuilder.h"
+#include "Lookup.h"
 #include "ObjectPrototype.h"
 #include "ObjectPrototype.h"
-#include "DateInstance.h"
 
 #if !PLATFORM(MAC) && HAVE(LANGINFO_H)
 #include <langinfo.h>
 
 #if !PLATFORM(MAC) && HAVE(LANGINFO_H)
 #include <langinfo.h>
@@ -356,7 +358,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue
     DateConversionBuffer time;
     formatDate(*gregorianDateTime, date);
     formatTime(*gregorianDateTime, time);
     DateConversionBuffer time;
     formatDate(*gregorianDateTime, date);
     formatTime(*gregorianDateTime, time);
-    return jsNontrivialString(exec, makeString(date, " ", time));
+    return jsMakeNontrivialString(exec, date, " ", time);
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -373,7 +375,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal
     DateConversionBuffer time;
     formatDateUTCVariant(*gregorianDateTime, date);
     formatTimeUTC(*gregorianDateTime, time);
     DateConversionBuffer time;
     formatDateUTCVariant(*gregorianDateTime, date);
     formatTimeUTC(*gregorianDateTime, time);
-    return jsNontrivialString(exec, makeString(date, " ", time));
+    return jsMakeNontrivialString(exec, date, " ", time);
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -499,7 +501,7 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal
     DateConversionBuffer time;
     formatDateUTCVariant(*gregorianDateTime, date);
     formatTimeUTC(*gregorianDateTime, time);
     DateConversionBuffer time;
     formatDateUTCVariant(*gregorianDateTime, date);
     formatTimeUTC(*gregorianDateTime, time);
-    return jsNontrivialString(exec, makeString(date, " ", time));
+    return jsMakeNontrivialString(exec, date, " ", time);
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 }
 
 JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
index ddd4bc4f5e1398ab60626d0ee06623b3cecdbc4c..69464b75fd5fc552987b84e34859d6c9301b8460 100644 (file)
@@ -94,7 +94,7 @@ JSObject* Error::create(ExecState* exec, ErrorType type, const UString& message,
 
 JSObject* Error::create(ExecState* exec, ErrorType type, const char* message)
 {
 
 JSObject* Error::create(ExecState* exec, ErrorType type, const char* message)
 {
-    return create(exec, type, message, -1, -1, NULL);
+    return create(exec, type, message, -1, -1, UString());
 }
 
 JSObject* throwError(ExecState* exec, JSObject* error)
 }
 
 JSObject* throwError(ExecState* exec, JSObject* error)
@@ -105,21 +105,21 @@ JSObject* throwError(ExecState* exec, JSObject* error)
 
 JSObject* throwError(ExecState* exec, ErrorType type)
 {
 
 JSObject* throwError(ExecState* exec, ErrorType type)
 {
-    JSObject* error = Error::create(exec, type, UString(), -1, -1, NULL);
+    JSObject* error = Error::create(exec, type, UString(), -1, -1, UString());
     exec->setException(error);
     return error;
 }
 
 JSObject* throwError(ExecState* exec, ErrorType type, const UString& message)
 {
     exec->setException(error);
     return error;
 }
 
 JSObject* throwError(ExecState* exec, ErrorType type, const UString& message)
 {
-    JSObject* error = Error::create(exec, type, message, -1, -1, NULL);
+    JSObject* error = Error::create(exec, type, message, -1, -1, UString());
     exec->setException(error);
     return error;
 }
 
 JSObject* throwError(ExecState* exec, ErrorType type, const char* message)
 {
     exec->setException(error);
     return error;
 }
 
 JSObject* throwError(ExecState* exec, ErrorType type, const char* message)
 {
-    JSObject* error = Error::create(exec, type, message, -1, -1, NULL);
+    JSObject* error = Error::create(exec, type, message, -1, -1, UString());
     exec->setException(error);
     return error;
 }
     exec->setException(error);
     return error;
 }
index be9e4b8a120fb17ea3cb117534d07a5272bb4b2e..eb357337ce22e2a7ca4f73e6b29810f443e52151 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "JSFunction.h"
 #include "JSString.h"
 
 #include "JSFunction.h"
 #include "JSString.h"
+#include "JSStringBuilder.h"
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
 #include "UString.h"
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
 #include "UString.h"
@@ -55,11 +56,11 @@ JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec, JSObject*, JSValue
 
     if (!name.isUndefined()) {
         if (!message.isUndefined())
 
     if (!name.isUndefined()) {
         if (!message.isUndefined())
-            return jsNontrivialString(exec, makeString(name.toString(exec), ": ", message.toString(exec)));
+            return jsMakeNontrivialString(exec, name.toString(exec), ": ", message.toString(exec));
         return jsNontrivialString(exec, name.toString(exec));
     }
     if (!message.isUndefined())
         return jsNontrivialString(exec, name.toString(exec));
     }
     if (!message.isUndefined())
-        return jsNontrivialString(exec, makeString("Error: ", message.toString(exec)));
+        return jsMakeNontrivialString(exec, "Error: ", message.toString(exec));
     return jsNontrivialString(exec, "Error");
 }
 
     return jsNontrivialString(exec, "Error");
 }
 
index 9bb740e309c6f70cbeb01b17669dbbf2078ffba6..aee6f31255c734c36be9b83556319f2740f09386 100644 (file)
@@ -46,7 +46,7 @@ public:
     {
     }
 
     {
     }
 
-    virtual bool isWatchdogException() const { return true; }
+    virtual ComplType exceptionType() const { return Interrupted; }
 
     virtual UString toString(ExecState*) const { return "JavaScript execution exceeded timeout."; }
 };
 
     virtual UString toString(ExecState*) const { return "JavaScript execution exceeded timeout."; }
 };
@@ -56,9 +56,26 @@ JSValue createInterruptedExecutionException(JSGlobalData* globalData)
     return new (globalData) InterruptedExecutionError(globalData);
 }
 
     return new (globalData) InterruptedExecutionError(globalData);
 }
 
+class TerminatedExecutionError : public JSObject {
+public:
+    TerminatedExecutionError(JSGlobalData* globalData)
+        : JSObject(globalData->terminatedExecutionErrorStructure)
+    {
+    }
+
+    virtual ComplType exceptionType() const { return Terminated; }
+
+    virtual UString toString(ExecState*) const { return "JavaScript execution terminated."; }
+};
+
+JSValue createTerminatedExecutionException(JSGlobalData* globalData)
+{
+    return new (globalData) TerminatedExecutionError(globalData);
+}
+
 static JSValue 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);
+    return Error::create(exec, e, msg, -1, -1, UString());
 }
 
 JSValue createStackOverflowError(ExecState* exec)
 }
 
 JSValue createStackOverflowError(ExecState* exec)
@@ -188,4 +205,9 @@ JSObject* createNotAnObjectError(ExecState* exec, JSNotAnObjectErrorStub* error,
     return exception;
 }
 
     return exception;
 }
 
+JSValue throwOutOfMemoryError(ExecState* exec)
+{
+    return throwError(exec, GeneralError, "Out of memory");
+}
+
 } // namespace JSC
 } // namespace JSC
index e739d0954c7b0c73d1e78a4f0eba840bf3e0dae7..b15243922c543b142a712bbd0962cf121f9b3c32 100644 (file)
@@ -43,6 +43,7 @@ namespace JSC {
     struct Instruction;
     
     JSValue createInterruptedExecutionException(JSGlobalData*);
     struct Instruction;
     
     JSValue createInterruptedExecutionException(JSGlobalData*);
+    JSValue createTerminatedExecutionException(JSGlobalData*);
     JSValue createStackOverflowError(ExecState*);
     JSValue createTypeError(ExecState*, const char* message);
     JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
     JSValue createStackOverflowError(ExecState*);
     JSValue createTypeError(ExecState*, const char* message);
     JSValue createUndefinedVariableError(ExecState*, const Identifier&, unsigned bytecodeOffset, CodeBlock*);
@@ -51,6 +52,7 @@ namespace JSC {
     JSObject* createNotAConstructorError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
     JSValue createNotAFunctionError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
     JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, unsigned bytecodeOffset, CodeBlock*);
     JSObject* createNotAConstructorError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
     JSValue createNotAFunctionError(ExecState*, JSValue, unsigned bytecodeOffset, CodeBlock*);
     JSObject* createNotAnObjectError(ExecState*, JSNotAnObjectErrorStub*, unsigned bytecodeOffset, CodeBlock*);
+    JSValue throwOutOfMemoryError(ExecState*);
 
 } // namespace JSC
 
 
 } // namespace JSC
 
index bc18cc9a80a00f2f3125d26bb871936623a208a6..1916a234b86de813dd1df7ec0aa6d569198370b3 100644 (file)
@@ -139,6 +139,9 @@ void FunctionExecutable::compile(ExecState*, ScopeChainNode* scopeChainNode)
 
 void EvalExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
 {
 
 void EvalExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
 {
+#if ENABLE(INTERPRETER)
+    ASSERT(scopeChainNode->globalData->canUseJIT());
+#endif
     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
 
     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
 
@@ -150,6 +153,9 @@ void EvalExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChain
 
 void ProgramExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
 {
 
 void ProgramExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
 {
+#if ENABLE(INTERPRETER)
+    ASSERT(scopeChainNode->globalData->canUseJIT());
+#endif
     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
 
     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
 
@@ -161,6 +167,9 @@ void ProgramExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeCh
 
 void FunctionExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
 {
 
 void FunctionExecutable::generateJITCode(ExecState* exec, ScopeChainNode* scopeChainNode)
 {
+#if ENABLE(INTERPRETER)
+    ASSERT(scopeChainNode->globalData->canUseJIT());
+#endif
     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
 
     CodeBlock* codeBlock = &bytecode(exec, scopeChainNode);
     m_jitCode = JIT::compile(scopeChainNode->globalData, codeBlock);
 
@@ -198,8 +207,13 @@ ExceptionInfo* FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData
     ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
 
 #if ENABLE(JIT)
     ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
 
 #if ENABLE(JIT)
-    JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
-    ASSERT(newJITCode.size() == generatedJITCode().size());
+#if ENABLE(INTERPRETER)
+    if (globalData->canUseJIT())
+#endif
+    {
+        JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
+        ASSERT(newJITCode.size() == generatedJITCode().size());
+    }
 #endif
 
     globalData->functionCodeBlockBeingReparsed = 0;
 #endif
 
     globalData->functionCodeBlockBeingReparsed = 0;
@@ -223,8 +237,13 @@ ExceptionInfo* EvalExecutable::reparseExceptionInfo(JSGlobalData* globalData, Sc
     ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
 
 #if ENABLE(JIT)
     ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());
 
 #if ENABLE(JIT)
-    JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
-    ASSERT(newJITCode.size() == generatedJITCode().size());
+#if ENABLE(INTERPRETER)
+    if (globalData->canUseJIT())
+#endif
+    {
+        JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
+        ASSERT(newJITCode.size() == generatedJITCode().size());
+    }
 #endif
 
     return newCodeBlock->extractExceptionInfo();
 #endif
 
     return newCodeBlock->extractExceptionInfo();
@@ -272,7 +291,7 @@ UString FunctionExecutable::paramString() const
             builder.append(", ");
         builder.append(parameters[pos].ustring());
     }
             builder.append(", ");
         builder.append(parameters[pos].ustring());
     }
-    return builder.release();
+    return builder.build();
 }
 
 };
 }
 
 };
index f74abe93d4721b39d831e767dd385093cd481012..485cc0d6d65fbfd776eccbed676ac0c780db5c14 100644 (file)
@@ -82,10 +82,10 @@ namespace JSC {
 #if ENABLE(JIT)
     class NativeExecutable : public ExecutableBase {
     public:
 #if ENABLE(JIT)
     class NativeExecutable : public ExecutableBase {
     public:
-        NativeExecutable(ExecState* exec)
+        NativeExecutable(JITCode thunk)
             : ExecutableBase(NUM_PARAMETERS_IS_HOST)
         {
             : ExecutableBase(NUM_PARAMETERS_IS_HOST)
         {
-            m_jitCode = JITCode(JITCode::HostFunction(exec->globalData().jitStubs.ctiNativeCallThunk()));
+            m_jitCode = thunk;
         }
 
         ~NativeExecutable();
         }
 
         ~NativeExecutable();
@@ -284,7 +284,7 @@ namespace JSC {
 
         const Identifier& name() { return m_name; }
         size_t parameterCount() const { return m_parameters->size(); }
 
         const Identifier& name() { return m_name; }
         size_t parameterCount() const { return m_parameters->size(); }
-        size_t variableCount() const { return m_numVariables; }
+        unsigned variableCount() const { return m_numVariables; }
         UString paramString() const;
 
         void recompile(ExecState*);
         UString paramString() const;
 
         void recompile(ExecState*);
@@ -295,11 +295,11 @@ namespace JSC {
     private:
         FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
             : ScriptExecutable(globalData, source)
     private:
         FunctionExecutable(JSGlobalData* globalData, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
             : ScriptExecutable(globalData, source)
+            , m_numVariables(0)
             , m_forceUsesArguments(forceUsesArguments)
             , m_parameters(parameters)
             , m_codeBlock(0)
             , m_name(name)
             , m_forceUsesArguments(forceUsesArguments)
             , m_parameters(parameters)
             , m_codeBlock(0)
             , m_name(name)
-            , m_numVariables(0)
         {
             m_firstLine = firstLine;
             m_lastLine = lastLine;
         {
             m_firstLine = firstLine;
             m_lastLine = lastLine;
@@ -307,11 +307,11 @@ namespace JSC {
 
         FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
             : ScriptExecutable(exec, source)
 
         FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, int firstLine, int lastLine)
             : ScriptExecutable(exec, source)
+            , m_numVariables(0)
             , m_forceUsesArguments(forceUsesArguments)
             , m_parameters(parameters)
             , m_codeBlock(0)
             , m_name(name)
             , m_forceUsesArguments(forceUsesArguments)
             , m_parameters(parameters)
             , m_codeBlock(0)
             , m_name(name)
-            , m_numVariables(0)
         {
             m_firstLine = firstLine;
             m_lastLine = lastLine;
         {
             m_firstLine = firstLine;
             m_lastLine = lastLine;
@@ -319,11 +319,12 @@ namespace JSC {
 
         void compile(ExecState*, ScopeChainNode*);
 
 
         void compile(ExecState*, ScopeChainNode*);
 
-        bool m_forceUsesArguments;
+        unsigned m_numVariables : 31;
+        bool m_forceUsesArguments : 1;
+
         RefPtr<FunctionParameters> m_parameters;
         CodeBlock* m_codeBlock;
         Identifier m_name;
         RefPtr<FunctionParameters> m_parameters;
         CodeBlock* m_codeBlock;
         Identifier m_name;
-        size_t m_numVariables;
 
 #if ENABLE(JIT)
     public:
 
 #if ENABLE(JIT)
     public:
index 9d55dd109b00ffd40d9aa9ff0999faf6654b7c98..9b0b1bbe46cbd8e03b630a79c1095f47ca5d876f 100644 (file)
@@ -89,7 +89,7 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
         builder.append(") { ");
         builder.append(args.at(args.size() - 1).toString(exec));
         builder.append("\n})");
         builder.append(") { ");
         builder.append(args.at(args.size() - 1).toString(exec));
         builder.append("\n})");
-        program = builder.release();
+        program = builder.build();
     }
 
     int errLine;
     }
 
     int errLine;
index f08bd5e1f9d883c8dd814fe004ef8d57abca5e10..a77b5b27e9d1a856b4e808701274887375e1946d 100644 (file)
@@ -25,6 +25,7 @@
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSString.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSString.h"
+#include "JSStringBuilder.h"
 #include "Interpreter.h"
 #include "Lexer.h"
 #include "PrototypeFunction.h"
 #include "Interpreter.h"
 #include "Lexer.h"
 #include "PrototypeFunction.h"
@@ -90,13 +91,13 @@ JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSVa
             FunctionExecutable* executable = function->jsExecutable();
             UString sourceString = executable->source().toString();
             insertSemicolonIfNeeded(sourceString);
             FunctionExecutable* executable = function->jsExecutable();
             UString sourceString = executable->source().toString();
             insertSemicolonIfNeeded(sourceString);
-            return jsString(exec, makeString("function ", function->name(exec), "(", executable->paramString(), ") ", sourceString));
+            return jsMakeNontrivialString(exec, "function ", function->name(exec), "(", executable->paramString(), ") ", sourceString);
         }
     }
 
     if (thisValue.inherits(&InternalFunction::info)) {
         InternalFunction* function = asInternalFunction(thisValue);
         }
     }
 
     if (thisValue.inherits(&InternalFunction::info)) {
         InternalFunction* function = asInternalFunction(thisValue);
-        return jsString(exec, makeString("function ", function->name(exec), "() {\n    [native code]\n}"));
+        return jsMakeNontrivialString(exec, "function ", function->name(exec), "() {\n    [native code]\n}");
     }
 
     return throwError(exec, TypeError);
     }
 
     return throwError(exec, TypeError);
index 4e47361ec8eb9d63103dcf25bd00ebd944e7d631..27ffbe78a76294e1cb1b566645ce56787a7a67ab 100644 (file)
@@ -34,6 +34,7 @@ namespace JSC {
     // This is an internal value object which stores getter and setter functions
     // for a property.
     class GetterSetter : public JSCell {
     // This is an internal value object which stores getter and setter functions
     // for a property.
     class GetterSetter : public JSCell {
+        friend class JIT;
     public:
         GetterSetter(ExecState* exec)
             : JSCell(exec->globalData().getterSetterStructure.get())
     public:
         GetterSetter(ExecState* exec)
             : JSCell(exec->globalData().getterSetterStructure.get())
index 76e762c97e5750f979e1d42d4f8529c5a699be68..f2642a93f13bba05b437fe056ce9c95c78ca1d1f 100644 (file)
 #include "Identifier.h"
 
 #include "CallFrame.h"
 #include "Identifier.h"
 
 #include "CallFrame.h"
+#include "NumericStrings.h"
 #include <new> // for placement new
 #include <string.h> // for strlen
 #include <wtf/Assertions.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/HashSet.h>
 #include <new> // for placement new
 #include <string.h> // for strlen
 #include <wtf/Assertions.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/HashSet.h>
+#include <wtf/WTFThreadData.h>
+#include <wtf/text/StringHash.h>
 
 using WTF::ThreadSpecific;
 
 namespace JSC {
 
 
 using WTF::ThreadSpecific;
 
 namespace JSC {
 
-typedef HashMap<const char*, RefPtr<UString::Rep>, PtrHash<const char*> > LiteralIdentifierTable;
-
-class IdentifierTable : public FastAllocBase {
-public:
-    ~IdentifierTable()
-    {
-        HashSet<UString::Rep*>::iterator end = m_table.end();
-        for (HashSet<UString::Rep*>::iterator iter = m_table.begin(); iter != end; ++iter)
-            (*iter)->setIsIdentifier(false);
-    }
-    
-    std::pair<HashSet<UString::Rep*>::iterator, bool> add(UString::Rep* value)
-    {
-        std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add(value);
-        (*result.first)->setIsIdentifier(true);
-        return result;
-    }
-
-    template<typename U, typename V>
-    std::pair<HashSet<UString::Rep*>::iterator, bool> add(U value)
-    {
-        std::pair<HashSet<UString::Rep*>::iterator, bool> result = m_table.add<U, V>(value);
-        (*result.first)->setIsIdentifier(true);
-        return result;
-    }
-
-    void remove(UString::Rep* r) { m_table.remove(r); }
-
-    LiteralIdentifierTable& literalTable() { return m_literalTable; }
-
-private:
-    HashSet<UString::Rep*> m_table;
-    LiteralIdentifierTable m_literalTable;
-};
+IdentifierTable::~IdentifierTable()
+{
+    HashSet<StringImpl*>::iterator end = m_table.end();
+    for (HashSet<StringImpl*>::iterator iter = m_table.begin(); iter != end; ++iter)
+        (*iter)->setIsIdentifier(false);
+}
+std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(StringImpl* value)
+{
+    std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add(value);
+    (*result.first)->setIsIdentifier(true);
+    return result;
+}
+template<typename U, typename V>
+std::pair<HashSet<StringImpl*>::iterator, bool> IdentifierTable::add(U value)
+{
+    std::pair<HashSet<StringImpl*>::iterator, bool> result = m_table.add<U, V>(value);
+    (*result.first)->setIsIdentifier(true);
+    return result;
+}
 
 IdentifierTable* createIdentifierTable()
 {
 
 IdentifierTable* createIdentifierTable()
 {
@@ -79,26 +67,26 @@ void deleteIdentifierTable(IdentifierTable* table)
 
 bool Identifier::equal(const UString::Rep* r, const char* s)
 {
 
 bool Identifier::equal(const UString::Rep* r, const char* s)
 {
-    int length = r->size();
-    const UChar* d = r->data();
+    int length = r->length();
+    const UChar* d = r->characters();
     for (int i = 0; i != length; ++i)
         if (d[i] != (unsigned char)s[i])
             return false;
     return s[length] == 0;
 }
 
     for (int i = 0; i != length; ++i)
         if (d[i] != (unsigned char)s[i])
             return false;
     return s[length] == 0;
 }
 
-bool Identifier::equal(const UString::Rep* r, const UChar* s, int length)
+bool Identifier::equal(const UString::Rep* r, const UChar* s, unsigned length)
 {
 {
-    if (r->size() != length)
+    if (r->length() != length)
         return false;
         return false;
-    const UChar* d = r->data();
-    for (int i = 0; i != length; ++i)
+    const UChar* d = r->characters();
+    for (unsigned i = 0; i != length; ++i)
         if (d[i] != s[i])
             return false;
     return true;
 }
 
         if (d[i] != s[i])
             return false;
     return true;
 }
 
-struct CStringTranslator {
+struct IdentifierCStringTranslator {
     static unsigned hash(const char* c)
     {
         return UString::Rep::computeHash(c);
     static unsigned hash(const char* c)
     {
         return UString::Rep::computeHash(c);
@@ -123,14 +111,10 @@ struct CStringTranslator {
 
 PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
 {
 
 PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
 {
-    if (!c) {
-        UString::Rep::null().hash();
-        return &UString::Rep::null();
-    }
-    if (!c[0]) {
-        UString::Rep::empty().hash();
-        return &UString::Rep::empty();
-    }
+    if (!c)
+        return UString::null().rep();
+    if (!c[0])
+        return UString::Rep::empty();
     if (!c[1])
         return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
 
     if (!c[1])
         return add(globalData, globalData->smallStrings.singleCharacterStringRep(static_cast<unsigned char>(c[0])));
 
@@ -141,7 +125,7 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c
     if (iter != literalIdentifierTable.end())
         return iter->second;
 
     if (iter != literalIdentifierTable.end())
         return iter->second;
 
-    pair<HashSet<UString::Rep*>::iterator, bool> addResult = identifierTable.add<const char*, CStringTranslator>(c);
+    pair<HashSet<UString::Rep*>::iterator, bool> addResult = identifierTable.add<const char*, IdentifierCStringTranslator>(c);
 
     // If the string is newly-translated, then we need to adopt it.
     // The boolean in the pair tells us if that is so.
 
     // If the string is newly-translated, then we need to adopt it.
     // The boolean in the pair tells us if that is so.
@@ -162,7 +146,7 @@ struct UCharBuffer {
     unsigned int length;
 };
 
     unsigned int length;
 };
 
-struct UCharBufferTranslator {
+struct IdentifierUCharBufferTranslator {
     static unsigned hash(const UCharBuffer& buf)
     {
         return UString::Rep::computeHash(buf.s, buf.length);
     static unsigned hash(const UCharBuffer& buf)
     {
         return UString::Rep::computeHash(buf.s, buf.length);
@@ -191,12 +175,10 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar*
         if (c <= 0xFF)
             return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
     }
         if (c <= 0xFF)
             return add(globalData, globalData->smallStrings.singleCharacterStringRep(c));
     }
-    if (!length) {
-        UString::Rep::empty().hash();
-        return &UString::Rep::empty();
-    }
+    if (!length)
+        return UString::Rep::empty();
     UCharBuffer buf = {s, length}; 
     UCharBuffer buf = {s, length}; 
-    pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, UCharBufferTranslator>(buf);
+    pair<HashSet<UString::Rep*>::iterator, bool> addResult = globalData->identifierTable->add<UCharBuffer, IdentifierUCharBufferTranslator>(buf);
 
     // If the string is newly-translated, then we need to adopt it.
     // The boolean in the pair tells us if that is so.
 
     // If the string is newly-translated, then we need to adopt it.
     // The boolean in the pair tells us if that is so.
@@ -211,21 +193,18 @@ PassRefPtr<UString::Rep> Identifier::add(ExecState* exec, const UChar* s, int le
 PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UString::Rep* r)
 {
     ASSERT(!r->isIdentifier());
 PassRefPtr<UString::Rep> Identifier::addSlowCase(JSGlobalData* globalData, UString::Rep* r)
 {
     ASSERT(!r->isIdentifier());
-    if (r->size() == 1) {
-        UChar c = r->data()[0];
+    // The empty & null strings are static singletons, and static strings are handled
+    // in ::add() in the header, so we should never get here with a zero length string.
+    ASSERT(r->length());
+
+    if (r->length() == 1) {
+        UChar c = r->characters()[0];
         if (c <= 0xFF)
             r = globalData->smallStrings.singleCharacterStringRep(c);
         if (c <= 0xFF)
             r = globalData->smallStrings.singleCharacterStringRep(c);
-            if (r->isIdentifier()) {
-#ifndef NDEBUG
-                checkSameIdentifierTable(globalData, r);
-#endif
+            if (r->isIdentifier())
                 return r;
                 return r;
-            }
-    }
-    if (!r->size()) {
-        UString::Rep::empty().hash();
-        return &UString::Rep::empty();
     }
     }
+
     return *globalData->identifierTable->add(r).first;
 }
 
     return *globalData->identifierTable->add(r).first;
 }
 
@@ -234,64 +213,41 @@ PassRefPtr<UString::Rep> Identifier::addSlowCase(ExecState* exec, UString::Rep*
     return addSlowCase(&exec->globalData(), r);
 }
 
     return addSlowCase(&exec->globalData(), r);
 }
 
-void Identifier::remove(UString::Rep* r)
+Identifier Identifier::from(ExecState* exec, unsigned value)
 {
 {
-    currentIdentifierTable()->remove(r);
+    return Identifier(exec, exec->globalData().numericStrings.add(value));
 }
 
 }
 
-#ifndef NDEBUG
-
-void Identifier::checkSameIdentifierTable(ExecState* exec, UString::Rep*)
+Identifier Identifier::from(ExecState* exec, int value)
 {
 {
-    ASSERT_UNUSED(exec, exec->globalData().identifierTable == currentIdentifierTable());
+    return Identifier(exec, exec->globalData().numericStrings.add(value));
 }
 
 }
 
-void Identifier::checkSameIdentifierTable(JSGlobalData* globalData, UString::Rep*)
+Identifier Identifier::from(ExecState* exec, double value)
 {
 {
-    ASSERT_UNUSED(globalData, globalData->identifierTable == currentIdentifierTable());
+    return Identifier(exec, exec->globalData().numericStrings.add(value));
 }
 
 }
 
-#else
-
-void Identifier::checkSameIdentifierTable(ExecState*, UString::Rep*)
-{
-}
+#ifndef NDEBUG
 
 
-void Identifier::checkSameIdentifierTable(JSGlobalData*, UString::Rep*)
+void Identifier::checkCurrentIdentifierTable(JSGlobalData* globalData)
 {
 {
+    // Check the identifier table accessible through the threadspecific matches the
+    // globalData's identifier table.
+    ASSERT_UNUSED(globalData, globalData->identifierTable == wtfThreadData().currentIdentifierTable());
 }
 
 }
 
-#endif
-
-ThreadSpecific<ThreadIdentifierTableData>* g_identifierTableSpecific = 0;
-ThreadIdentifierTableData* g_identifierTableMain = 0;
-
-#if ENABLE(JSC_MULTIPLE_THREADS)
-
-pthread_once_t createIdentifierTableSpecificOnce = PTHREAD_ONCE_INIT;
-static void createIdentifierTableSpecificCallback()
+void Identifier::checkCurrentIdentifierTable(ExecState* exec)
 {
 {
-    ASSERT(!g_identifierTableSpecific);
-    g_identifierTableSpecific = new ThreadSpecific<ThreadIdentifierTableData>();
-    ASSERT(!g_identifierTableMain);
-    g_identifierTableMain = new ThreadIdentifierTableData();
-}
-void createIdentifierTableSpecific()
-{
-    pthread_once(&createIdentifierTableSpecificOnce, createIdentifierTableSpecificCallback);
-    ASSERT(g_identifierTableSpecific);
-    ASSERT(g_identifierTableMain);
+    checkCurrentIdentifierTable(&exec->globalData());
 }
 
 }
 
-#else 
+#else
 
 
-void createIdentifierTableSpecific()
-{
-    ASSERT(!g_identifierTableSpecific);
-    g_identifierTableSpecific = new ThreadSpecific<ThreadIdentifierTableData>();
-    ASSERT(!g_identifierTableMain);
-    g_identifierTableMain = new ThreadIdentifierTableData();
-}
+// These only exists so that our exports are the same for debug and release builds.
+// This would be an ASSERT_NOT_REACHED(), but we're in NDEBUG only code here!
+void Identifier::checkCurrentIdentifierTable(JSGlobalData*) { CRASH(); }
+void Identifier::checkCurrentIdentifierTable(ExecState*) { CRASH(); }
 
 #endif
 
 
 #endif
 
index 35822258ef37a2d4fd9c565d4450d73b16fd85f3..2f16bbf52cac13c038067bf85826c3f3808f534d 100644 (file)
@@ -54,9 +54,9 @@ namespace JSC {
         
         const char* ascii() const { return _ustring.ascii(); }
         
         
         const char* ascii() const { return _ustring.ascii(); }
         
-        static Identifier from(ExecState* exec, unsigned y) { return Identifier(exec, UString::from(y)); }
-        static Identifier from(ExecState* exec, int y) { return Identifier(exec, UString::from(y)); }
-        static Identifier from(ExecState* exec, double y) { return Identifier(exec, UString::from(y)); }
+        static Identifier from(ExecState* exec, unsigned y);
+        static Identifier from(ExecState* exec, int y);
+        static Identifier from(ExecState* exec, double y);
         
         bool isNull() const { return _ustring.isNull(); }
         bool isEmpty() const { return _ustring.isEmpty(); }
         
         bool isNull() const { return _ustring.isNull(); }
         bool isEmpty() const { return _ustring.isEmpty(); }
@@ -73,11 +73,9 @@ namespace JSC {
         friend bool operator==(const Identifier&, const char*);
         friend bool operator!=(const Identifier&, const char*);
     
         friend bool operator==(const Identifier&, const char*);
         friend bool operator!=(const Identifier&, const char*);
     
-        static void remove(UString::Rep*);
-
         static bool equal(const UString::Rep*, const char*);
         static bool equal(const UString::Rep*, const char*);
-        static bool equal(const UString::Rep*, const UChar*, int length);
-        static bool equal(const UString::Rep* a, const UString::Rep* b) { return JSC::equal(a, b); }
+        static bool equal(const UString::Rep*, const UChar*, unsigned length);
+        static bool equal(const UString::Rep* a, const UString::Rep* b) { return ::equal(a, b); }
 
         static PassRefPtr<UString::Rep> add(ExecState*, const char*); // Only to be used with string literals.
         static PassRefPtr<UString::Rep> add(JSGlobalData*, const char*); // Only to be used with string literals.
 
         static PassRefPtr<UString::Rep> add(ExecState*, const char*); // Only to be used with string literals.
         static PassRefPtr<UString::Rep> add(JSGlobalData*, const char*); // Only to be used with string literals.
@@ -93,30 +91,28 @@ namespace JSC {
 
         static PassRefPtr<UString::Rep> add(ExecState* exec, UString::Rep* r)
         {
 
         static PassRefPtr<UString::Rep> add(ExecState* exec, UString::Rep* r)
         {
-            if (r->isIdentifier()) {
 #ifndef NDEBUG
 #ifndef NDEBUG
-                checkSameIdentifierTable(exec, r);
+            checkCurrentIdentifierTable(exec);
 #endif
 #endif
+            if (r->isIdentifier())
                 return r;
                 return r;
-            }
             return addSlowCase(exec, r);
         }
         static PassRefPtr<UString::Rep> add(JSGlobalData* globalData, UString::Rep* r)
         {
             return addSlowCase(exec, r);
         }
         static PassRefPtr<UString::Rep> add(JSGlobalData* globalData, UString::Rep* r)
         {
-            if (r->isIdentifier()) {
 #ifndef NDEBUG
 #ifndef NDEBUG
-                checkSameIdentifierTable(globalData, r);
+            checkCurrentIdentifierTable(globalData);
 #endif
 #endif
+            if (r->isIdentifier())
                 return r;
                 return r;
-            }
             return addSlowCase(globalData, r);
         }
 
         static PassRefPtr<UString::Rep> addSlowCase(ExecState*, UString::Rep* r);
         static PassRefPtr<UString::Rep> addSlowCase(JSGlobalData*, UString::Rep* r);
 
             return addSlowCase(globalData, r);
         }
 
         static PassRefPtr<UString::Rep> addSlowCase(ExecState*, UString::Rep* r);
         static PassRefPtr<UString::Rep> addSlowCase(JSGlobalData*, UString::Rep* r);
 
-        static void checkSameIdentifierTable(ExecState*, UString::Rep*);
-        static void checkSameIdentifierTable(JSGlobalData*, UString::Rep*);
+        static void checkCurrentIdentifierTable(ExecState*);
+        static void checkCurrentIdentifierTable(JSGlobalData*);
     };
     
     inline bool operator==(const Identifier& a, const Identifier& b)
     };
     
     inline bool operator==(const Identifier& a, const Identifier& b)
@@ -142,97 +138,6 @@ namespace JSC {
     IdentifierTable* createIdentifierTable();
     void deleteIdentifierTable(IdentifierTable*);
 
     IdentifierTable* createIdentifierTable();
     void deleteIdentifierTable(IdentifierTable*);
 
-    struct ThreadIdentifierTableData {
-        ThreadIdentifierTableData()
-            : defaultIdentifierTable(0)
-            , currentIdentifierTable(0)
-        {
-        }
-
-        IdentifierTable* defaultIdentifierTable;
-        IdentifierTable* currentIdentifierTable;
-    };
-
-    extern WTF::ThreadSpecific<ThreadIdentifierTableData>* g_identifierTableSpecific;
-    extern ThreadIdentifierTableData* g_identifierTableMain;
-    void createIdentifierTableSpecific();
-
-    inline IdentifierTable* defaultIdentifierTable()
-    {
-        if (isMainThread() || pthread_main_np()) {
-            if (!g_identifierTableMain)
-                createIdentifierTableSpecific();
-            return g_identifierTableMain->defaultIdentifierTable;
-        }
-        if (!g_identifierTableSpecific)
-            createIdentifierTableSpecific();
-        ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
-        return data.defaultIdentifierTable;
-    }
-
-    inline void setDefaultIdentifierTable(IdentifierTable* identifierTable)
-    {
-        if (isMainThread() || pthread_main_np()) {
-            if (!g_identifierTableMain)
-                createIdentifierTableSpecific();
-            g_identifierTableMain->defaultIdentifierTable = identifierTable;
-            return;
-        }
-        if (!g_identifierTableSpecific)
-            createIdentifierTableSpecific();
-        ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
-        data.defaultIdentifierTable = identifierTable;
-    }
-
-    inline IdentifierTable* currentIdentifierTable()
-    {
-        if (isMainThread() || pthread_main_np()) {
-            if (!g_identifierTableMain)
-                createIdentifierTableSpecific();
-            return g_identifierTableMain->currentIdentifierTable;
-        }
-        if (!g_identifierTableSpecific)
-            createIdentifierTableSpecific();
-        ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
-        return data.currentIdentifierTable;
-    }
-
-    inline IdentifierTable* setCurrentIdentifierTable(IdentifierTable* identifierTable)
-    {
-        if (isMainThread() || pthread_main_np()) {
-            if (!g_identifierTableMain)
-                createIdentifierTableSpecific();
-            IdentifierTable* oldIdentifierTable = g_identifierTableMain->currentIdentifierTable;
-            g_identifierTableMain->currentIdentifierTable = identifierTable;
-            return oldIdentifierTable;
-        }
-        if (!g_identifierTableSpecific)
-            createIdentifierTableSpecific();
-        ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
-        IdentifierTable* oldIdentifierTable = data.currentIdentifierTable;
-        data.currentIdentifierTable = identifierTable;
-        return oldIdentifierTable;
-    }
-
-    inline void resetCurrentIdentifierTable()
-    {
-        if (isMainThread() || pthread_main_np()) {
-            if (!g_identifierTableMain)
-                createIdentifierTableSpecific();
-            g_identifierTableMain->currentIdentifierTable = g_identifierTableMain->defaultIdentifierTable;
-            return;
-        }
-        if (!g_identifierTableSpecific)
-            createIdentifierTableSpecific();
-        ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
-        data.currentIdentifierTable = data.defaultIdentifierTable;
-    }
-
 } // namespace JSC
 
 #endif // Identifier_h
 } // namespace JSC
 
 #endif // Identifier_h
index 2605a9a7cde0e52532a1ea1e16f1657b6da8fc81..51d43ee224c3b42d178392a8a784dac0e6d72965 100644 (file)
@@ -36,6 +36,7 @@
 #include "UString.h"
 #include <wtf/DateMath.h>
 #include <wtf/Threading.h>
 #include "UString.h"
 #include <wtf/DateMath.h>
 #include <wtf/Threading.h>
+#include <wtf/WTFThreadData.h>
 
 using namespace WTF;
 
 
 using namespace WTF;
 
@@ -48,6 +49,7 @@ static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
 static void initializeThreadingOnce()
 {
     WTF::initializeThreading();
 static void initializeThreadingOnce()
 {
     WTF::initializeThreading();
+    wtfThreadData();
     initializeUString();
     JSGlobalData::storeVPtrs();
 #if ENABLE(JSC_MULTIPLE_THREADS)
     initializeUString();
     JSGlobalData::storeVPtrs();
 #if ENABLE(JSC_MULTIPLE_THREADS)
index c48d6288e5c8406d8b377d4cdebe70af386b729f..f68e795f31cbd8b0a298a35c31e5a26b056f8f22 100644 (file)
@@ -40,12 +40,12 @@ const ClassInfo* InternalFunction::classInfo() const
 InternalFunction::InternalFunction(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const Identifier& name)
     : JSObject(structure)
 {
 InternalFunction::InternalFunction(JSGlobalData* globalData, NonNullPassRefPtr<Structure> structure, const Identifier& name)
     : JSObject(structure)
 {
-    putDirect(globalData->propertyNames->name, jsString(globalData, name.ustring()), DontDelete | ReadOnly | DontEnum);
+    putDirect(globalData->propertyNames->name, jsString(globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
 }
 
 const UString& InternalFunction::name(ExecState* exec)
 {
 }
 
 const UString& InternalFunction::name(ExecState* exec)
 {
-    return asString(getDirect(exec->globalData().propertyNames->name))->value(exec);
+    return asString(getDirect(exec->globalData().propertyNames->name))->tryGetValue();
 }
 
 const UString InternalFunction::displayName(ExecState* exec)
 }
 
 const UString InternalFunction::displayName(ExecState* exec)
@@ -53,7 +53,7 @@ const UString InternalFunction::displayName(ExecState* exec)
     JSValue displayName = getDirect(exec->globalData().propertyNames->displayName);
     
     if (displayName && isJSString(&exec->globalData(), displayName))
     JSValue displayName = getDirect(exec->globalData().propertyNames->displayName);
     
     if (displayName && isJSString(&exec->globalData(), displayName))
-        return asString(displayName)->value(exec);
+        return asString(displayName)->tryGetValue();
     
     return UString::null();
 }
     
     return UString::null();
 }
index b5016c24230ededb5491b83220527d0a93ba0115..10ded4cd4418bd9bcd8f3c10c57d9bae50f6f81f 100644 (file)
@@ -23,8 +23,6 @@
 #ifndef JSAPIValueWrapper_h
 #define JSAPIValueWrapper_h
 
 #ifndef JSAPIValueWrapper_h
 #define JSAPIValueWrapper_h
 
-#include <wtf/Platform.h>
-
 #include "JSCell.h"
 #include "CallFrame.h"
 
 #include "JSCell.h"
 #include "CallFrame.h"
 
index 22fdaafd46a1037327d53974366a65f44be28963..f468ff1e745c0578d56db4aa604d0a5ee437a615 100644 (file)
@@ -134,14 +134,15 @@ JSObject* JSActivation::toThisObject(ExecState* exec) const
     return exec->globalThisValue();
 }
 
     return exec->globalThisValue();
 }
 
-bool JSActivation::isDynamicScope() const
+bool JSActivation::isDynamicScope(bool& requiresDynamicChecks) const
 {
 {
-    return d()->functionExecutable->usesEval();
+    requiresDynamicChecks = d()->functionExecutable->usesEval();
+    return false;
 }
 
 }
 
-JSValue JSActivation::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSActivation::argumentsGetter(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    JSActivation* activation = asActivation(slot.slotBase());
+    JSActivation* activation = asActivation(slotBase);
 
     if (activation->d()->functionExecutable->usesArguments()) {
         PropertySlot slot;
 
     if (activation->d()->functionExecutable->usesArguments()) {
         PropertySlot slot;
index 761bee4a48109695db9ccddb45a74231643ad579..10a8dbd1176deb6e4737b37dd5cf734bcc1ea072 100644 (file)
@@ -31,7 +31,6 @@
 
 #include "CodeBlock.h"
 #include "JSVariableObject.h"
 
 #include "CodeBlock.h"
 #include "JSVariableObject.h"
-#include "RegisterFile.h"
 #include "SymbolTable.h"
 #include "Nodes.h"
 
 #include "SymbolTable.h"
 #include "Nodes.h"
 
@@ -48,7 +47,7 @@ namespace JSC {
 
         virtual void markChildren(MarkStack&);
 
 
         virtual void markChildren(MarkStack&);
 
-        virtual bool isDynamicScope() const;
+        virtual bool isDynamicScope(bool& requiresDynamicChecks) const;
 
         virtual bool isActivationObject() const { return true; }
 
 
         virtual bool isActivationObject() const { return true; }
 
@@ -89,7 +88,7 @@ namespace JSC {
             RefPtr<FunctionExecutable> functionExecutable;
         };
         
             RefPtr<FunctionExecutable> functionExecutable;
         };
         
-        static JSValue argumentsGetter(ExecState*, const Identifier&, const PropertySlot&);
+        static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
         NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
 
         JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
         NEVER_INLINE PropertySlot::GetValueFunc getArgumentsGetter();
 
         JSActivationData* d() const { return static_cast<JSActivationData*>(JSVariableObject::d); }
index 5ec43c73ea0e51d7a6216bfa1afe2a96ebad8e52..ae9e038f74497b1f79d33c166e778fde81a20461 100644 (file)
@@ -151,7 +151,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength)
     m_vectorLength = initialCapacity;
     m_storage->m_numValuesInVector = 0;
     m_storage->m_sparseValueMap = 0;
     m_vectorLength = initialCapacity;
     m_storage->m_numValuesInVector = 0;
     m_storage->m_sparseValueMap = 0;
-    m_storage->lazyCreationData = 0;
+    m_storage->subclassData = 0;
     m_storage->reportedMapCapacity = 0;
 
     JSValue* vector = m_storage->m_vector;
     m_storage->reportedMapCapacity = 0;
 
     JSValue* vector = m_storage->m_vector;
@@ -173,7 +173,7 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
     m_vectorLength = initialCapacity;
     m_storage->m_numValuesInVector = initialCapacity;
     m_storage->m_sparseValueMap = 0;
     m_vectorLength = initialCapacity;
     m_storage->m_numValuesInVector = initialCapacity;
     m_storage->m_sparseValueMap = 0;
-    m_storage->lazyCreationData = 0;
+    m_storage->subclassData = 0;
     m_storage->reportedMapCapacity = 0;
 
     size_t i = 0;
     m_storage->reportedMapCapacity = 0;
 
     size_t i = 0;
@@ -1022,14 +1022,14 @@ unsigned JSArray::compactForSorting()
     return numDefined;
 }
 
     return numDefined;
 }
 
-void* JSArray::lazyCreationData()
+void* JSArray::subclassData() const
 {
 {
-    return m_storage->lazyCreationData;
+    return m_storage->subclassData;
 }
 
 }
 
-void JSArray::setLazyCreationData(void* d)
+void JSArray::setSubclassData(void* d)
 {
 {
-    m_storage->lazyCreationData = d;
+    m_storage->subclassData = d;
 }
 
 #if CHECK_ARRAY_CONSISTENCY
 }
 
 #if CHECK_ARRAY_CONSISTENCY
index ad6ee88c92e0bb504652cd81e7d248548c7eb89b..f65f2bcf70ebf9869f7b7c42c86aac3777b10d88 100644 (file)
@@ -31,7 +31,7 @@ namespace JSC {
         unsigned m_length;
         unsigned m_numValuesInVector;
         SparseArrayValueMap* m_sparseValueMap;
         unsigned m_length;
         unsigned m_numValuesInVector;
         SparseArrayValueMap* m_sparseValueMap;
-        void* lazyCreationData; // A JSArray subclass can use this to fill the vector lazily.
+        void* subclassData; // A JSArray subclass can use this to fill the vector lazily.
         size_t reportedMapCapacity;
         JSValue m_vector[1];
     };
         size_t reportedMapCapacity;
         JSValue m_vector[1];
     };
@@ -101,8 +101,8 @@ namespace JSC {
         virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         virtual void markChildren(MarkStack&);
 
         virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         virtual void markChildren(MarkStack&);
 
-        void* lazyCreationData();
-        void setLazyCreationData(void*);
+        void* subclassData() const;
+        void setSubclassData(void*);
 
     private:
         virtual const ClassInfo* classInfo() const { return &info; }
 
     private:
         virtual const ClassInfo* classInfo() const { return &info; }
index 869fbfc883e0ab2bd0d0a859090a02e43c2a36cf..0cc1ab1b7a6e419534e7e52d7b8b483480efd3be 100644 (file)
@@ -163,16 +163,6 @@ JSObject* JSCell::toThisObject(ExecState* exec) const
     return toObject(exec);
 }
 
     return toObject(exec);
 }
 
-UString JSCell::toThisString(ExecState* exec) const
-{
-    return toThisObject(exec)->toString(exec);
-}
-
-JSString* JSCell::toThisJSString(ExecState* exec)
-{
-    return jsString(exec, toThisString(exec));
-}
-
 const ClassInfo* JSCell::classInfo() const
 {
     return 0;
 const ClassInfo* JSCell::classInfo() const
 {
     return 0;
index 3c8c82910274a7dd4522a55ba68401eb2f852cdb..ae5aca3bf422eccde0516fce73fdc44cf66683f6 100644 (file)
@@ -107,18 +107,21 @@ namespace JSC {
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
 
         virtual JSObject* toThisObject(ExecState*) const;
         virtual bool deleteProperty(ExecState*, unsigned propertyName);
 
         virtual JSObject* toThisObject(ExecState*) const;
-        virtual UString toThisString(ExecState*) const;
-        virtual JSString* toThisJSString(ExecState*);
         virtual JSValue getJSNumber();
         void* vptr() { return *reinterpret_cast<void**>(this); }
         void setVPtr(void* vptr) { *reinterpret_cast<void**>(this) = vptr; }
 
         virtual JSValue getJSNumber();
         void* vptr() { return *reinterpret_cast<void**>(this); }
         void setVPtr(void* vptr) { *reinterpret_cast<void**>(this) = vptr; }
 
+        // FIXME: Rename getOwnPropertySlot to virtualGetOwnPropertySlot, and
+        // fastGetOwnPropertySlot to getOwnPropertySlot. Callers should always
+        // call this function, not its slower virtual counterpart. (For integer
+        // property names, we want a similar interface with appropriate optimizations.)
+        bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
+
     protected:
         static const unsigned AnonymousSlotCount = 0;
 
     private:
         // Base implementation; for non-object classes implements getPropertySlot.
     protected:
         static const unsigned AnonymousSlotCount = 0;
 
     private:
         // Base implementation; for non-object classes implements getPropertySlot.
-        bool fastGetOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
         
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
         
@@ -301,11 +304,6 @@ namespace JSC {
         return asCell()->structure()->typeInfo().needsThisConversion();
     }
 
         return asCell()->structure()->typeInfo().needsThisConversion();
     }
 
-    inline UString JSValue::toThisString(ExecState* exec) const
-    {
-        return isCell() ? asCell()->toThisString(exec) : toString(exec);
-    }
-
     inline JSValue JSValue::getJSNumber()
     {
         if (isInt32() || isDouble())
     inline JSValue JSValue::getJSNumber()
     {
         if (isInt32() || isDouble())
index d213b4abdf19fad5d9922fb8446bd7d35d693507..89c4dae9f0f4b206f5852bd2535c14b06bf6757e 100644 (file)
@@ -56,10 +56,27 @@ JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure)
 {
 }
 
 {
 }
 
+JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeExecutable* thunk, NativeFunction func)
+    : Base(&exec->globalData(), structure, name)
+#if ENABLE(JIT)
+    , m_executable(thunk)
+#endif
+{
+#if ENABLE(JIT)
+    setNativeFunction(func);
+    putDirect(exec->propertyNames().length, jsNumber(exec, length), DontDelete | ReadOnly | DontEnum);
+#else
+    UNUSED_PARAM(thunk);
+    UNUSED_PARAM(length);
+    UNUSED_PARAM(func);
+    ASSERT_NOT_REACHED();
+#endif
+}
+
 JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
     : Base(&exec->globalData(), structure, name)
 #if ENABLE(JIT)
 JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func)
     : Base(&exec->globalData(), structure, name)
 #if ENABLE(JIT)
-    , m_executable(adoptRef(new NativeExecutable(exec)))
+    , m_executable(exec->globalData().jitStubs->ctiNativeCallThunk())
 #endif
 {
 #if ENABLE(JIT)
 #endif
 {
 #if ENABLE(JIT)
@@ -122,23 +139,23 @@ JSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args
     return exec->interpreter()->execute(jsExecutable(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
 }
 
     return exec->interpreter()->execute(jsExecutable(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot());
 }
 
-JSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSFunction::argumentsGetter(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    JSFunction* thisObj = asFunction(slot.slotBase());
+    JSFunction* thisObj = asFunction(slotBase);
     ASSERT(!thisObj->isHostFunction());
     return exec->interpreter()->retrieveArguments(exec, thisObj);
 }
 
     ASSERT(!thisObj->isHostFunction());
     return exec->interpreter()->retrieveArguments(exec, thisObj);
 }
 
-JSValue JSFunction::callerGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    JSFunction* thisObj = asFunction(slot.slotBase());
+    JSFunction* thisObj = asFunction(slotBase);
     ASSERT(!thisObj->isHostFunction());
     return exec->interpreter()->retrieveCaller(exec, thisObj);
 }
 
     ASSERT(!thisObj->isHostFunction());
     return exec->interpreter()->retrieveCaller(exec, thisObj);
 }
 
-JSValue JSFunction::lengthGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue JSFunction::lengthGetter(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    JSFunction* thisObj = asFunction(slot.slotBase());
+    JSFunction* thisObj = asFunction(slotBase);
     ASSERT(!thisObj->isHostFunction());
     return jsNumber(exec, thisObj->jsExecutable()->parameterCount());
 }
     ASSERT(!thisObj->isHostFunction());
     return jsNumber(exec, thisObj->jsExecutable()->parameterCount());
 }
@@ -162,17 +179,17 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
     }
 
     if (propertyName == exec->propertyNames().arguments) {
     }
 
     if (propertyName == exec->propertyNames().arguments) {
-        slot.setCustom(this, argumentsGetter);
+        slot.setCacheableCustom(this, argumentsGetter);
         return true;
     }
 
     if (propertyName == exec->propertyNames().length) {
         return true;
     }
 
     if (propertyName == exec->propertyNames().length) {
-        slot.setCustom(this, lengthGetter);
+        slot.setCacheableCustom(this, lengthGetter);
         return true;
     }
 
     if (propertyName == exec->propertyNames().caller) {
         return true;
     }
 
     if (propertyName == exec->propertyNames().caller) {
-        slot.setCustom(this, callerGetter);
+        slot.setCacheableCustom(this, callerGetter);
         return true;
     }
 
         return true;
     }
 
index 8cd4b511371ab0f40ca145ef1f34135f5fe77f2a..301b908117b550445a66c7e97422fea04b09de5b 100644 (file)
@@ -33,6 +33,7 @@ namespace JSC {
     class FunctionPrototype;
     class JSActivation;
     class JSGlobalObject;
     class FunctionPrototype;
     class JSActivation;
     class JSGlobalObject;
+    class NativeExecutable;
 
     class JSFunction : public InternalFunction {
         friend class JIT;
 
     class JSFunction : public InternalFunction {
         friend class JIT;
@@ -42,6 +43,7 @@ namespace JSC {
 
     public:
         JSFunction(ExecState*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
 
     public:
         JSFunction(ExecState*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeFunction);
+        JSFunction(ExecState*, NonNullPassRefPtr<Structure>, int length, const Identifier&, NativeExecutable*, NativeFunction);
         JSFunction(ExecState*, NonNullPassRefPtr<FunctionExecutable>, ScopeChainNode*);
         virtual ~JSFunction();
 
         JSFunction(ExecState*, NonNullPassRefPtr<FunctionExecutable>, ScopeChainNode*);
         virtual ~JSFunction();
 
@@ -90,9 +92,9 @@ namespace JSC {
 
         virtual const ClassInfo* classInfo() const { return &info; }
 
 
         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&);
+        static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
+        static JSValue callerGetter(ExecState*, JSValue, const Identifier&);
+        static JSValue lengthGetter(ExecState*, JSValue, const Identifier&);
 
         RefPtr<ExecutableBase> m_executable;
         ScopeChain& scopeChain()
 
         RefPtr<ExecutableBase> m_executable;
         ScopeChain& scopeChain()
index 45abc86de1f6bd6a641815d632e306530d817594..73e62633d1c1380c0c53c265a2bc8ae663618afa 100644 (file)
@@ -49,6 +49,8 @@
 #include "Lookup.h"
 #include "Nodes.h"
 #include "Parser.h"
 #include "Lookup.h"
 #include "Nodes.h"
 #include "Parser.h"
+#include "RegExpCache.h"
+#include <wtf/WTFThreadData.h>
 
 #if ENABLE(JSC_MULTIPLE_THREADS)
 #include <wtf/Threading.h>
 
 #if ENABLE(JSC_MULTIPLE_THREADS)
 #include <wtf/Threading.h>
@@ -56,6 +58,7 @@
 
 #if PLATFORM(MAC)
 #include "ProfilerServer.h"
 
 #if PLATFORM(MAC)
 #include "ProfilerServer.h"
+#include <CoreFoundation/CoreFoundation.h>
 #endif
 
 using namespace WTF;
 #endif
 
 using namespace WTF;
@@ -102,8 +105,8 @@ void JSGlobalData::storeVPtrs()
     jsFunction->~JSCell();
 }
 
     jsFunction->~JSCell();
 }
 
-JSGlobalData::JSGlobalData(bool isShared)
-    : isSharedInstance(isShared)
+JSGlobalData::JSGlobalData(GlobalDataType globalDataType, ThreadStackType threadStackType)
+    : globalDataType(globalDataType)
     , clientData(0)
     , arrayTable(fastNew<HashTable>(JSC::arrayTable))
     , dateTable(fastNew<HashTable>(JSC::dateTable))
     , clientData(0)
     , arrayTable(fastNew<HashTable>(JSC::arrayTable))
     , dateTable(fastNew<HashTable>(JSC::dateTable))
@@ -115,6 +118,7 @@ JSGlobalData::JSGlobalData(bool isShared)
     , stringTable(fastNew<HashTable>(JSC::stringTable))
     , activationStructure(JSActivation::createStructure(jsNull()))
     , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
     , stringTable(fastNew<HashTable>(JSC::stringTable))
     , activationStructure(JSActivation::createStructure(jsNull()))
     , interruptedExecutionErrorStructure(JSObject::createStructure(jsNull()))
+    , terminatedExecutionErrorStructure(JSObject::createStructure(jsNull()))
     , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
     , stringStructure(JSString::createStructure(jsNull()))
     , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
     , staticScopeStructure(JSStaticScopeObject::createStructure(jsNull()))
     , stringStructure(JSString::createStructure(jsNull()))
     , notAnObjectErrorStubStructure(JSNotAnObjectErrorStub::createStructure(jsNull()))
@@ -126,15 +130,12 @@ JSGlobalData::JSGlobalData(bool isShared)
 #if USE(JSVALUE32)
     , numberStructure(JSNumberCell::createStructure(jsNull()))
 #endif
 #if USE(JSVALUE32)
     , numberStructure(JSNumberCell::createStructure(jsNull()))
 #endif
-    , identifierTable(createIdentifierTable())
+    , identifierTable(globalDataType == Default ? wtfThreadData().currentIdentifierTable() : createIdentifierTable())
     , propertyNames(new CommonIdentifiers(this))
     , emptyList(new MarkedArgumentBuffer)
     , lexer(new Lexer(this))
     , parser(new Parser)
     , interpreter(new Interpreter)
     , propertyNames(new CommonIdentifiers(this))
     , 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)
     , heap(this)
     , initializingLazyNumericCompareFunction(false)
     , head(0)
@@ -143,14 +144,38 @@ JSGlobalData::JSGlobalData(bool isShared)
     , firstStringifierToMark(0)
     , markStack(jsArrayVPtr)
     , cachedUTCOffset(NaN)
     , firstStringifierToMark(0)
     , markStack(jsArrayVPtr)
     , cachedUTCOffset(NaN)
-    , weakRandom(static_cast<int>(currentTime()))
+    , maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
+    , m_regExpCache(new RegExpCache(this))
 #ifndef NDEBUG
 #ifndef NDEBUG
-    , mainThreadOnly(false)
+    , exclusiveThread(0)
 #endif
 {
 #if PLATFORM(MAC)
     startProfilerServerIfNeeded();
 #endif
 #endif
 {
 #if PLATFORM(MAC)
     startProfilerServerIfNeeded();
 #endif
+#if ENABLE(JIT) && ENABLE(INTERPRETER)
+#if PLATFORM(CF)
+    CFStringRef canUseJITKey = CFStringCreateWithCString(0 , "JavaScriptCoreUseJIT", kCFStringEncodingMacRoman);
+    CFBooleanRef canUseJIT = (CFBooleanRef)CFPreferencesCopyAppValue(canUseJITKey, kCFPreferencesCurrentApplication);
+    if (canUseJIT) {
+        m_canUseJIT = kCFBooleanTrue == canUseJIT;
+        CFRelease(canUseJIT);
+    } else
+        m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
+    CFRelease(canUseJITKey);
+#elif OS(UNIX)
+    m_canUseJIT = !getenv("JavaScriptCoreUseJIT");
+#else
+    m_canUseJIT = true;
+#endif
+#endif
+#if ENABLE(JIT)
+#if ENABLE(INTERPRETER)
+    if (m_canUseJIT)
+        m_canUseJIT = executableAllocator.isValid();
+#endif
+    jitStubs.set(new JITThunks(this));
+#endif
 }
 
 JSGlobalData::~JSGlobalData()
 }
 
 JSGlobalData::~JSGlobalData()
@@ -189,28 +214,27 @@ JSGlobalData::~JSGlobalData()
     delete emptyList;
 
     delete propertyNames;
     delete emptyList;
 
     delete propertyNames;
-    deleteIdentifierTable(identifierTable);
+    if (globalDataType != Default)
+        deleteIdentifierTable(identifierTable);
 
     delete clientData;
 
     delete clientData;
+    delete m_regExpCache;
 }
 
 }
 
-PassRefPtr<JSGlobalData> JSGlobalData::createNonDefault()
+PassRefPtr<JSGlobalData> JSGlobalData::createContextGroup(ThreadStackType type)
 {
 {
-    return adoptRef(new JSGlobalData(false));
+    return adoptRef(new JSGlobalData(APIContextGroup, type));
 }
 
 }
 
-PassRefPtr<JSGlobalData> JSGlobalData::create()
+PassRefPtr<JSGlobalData> JSGlobalData::create(ThreadStackType type)
 {
 {
-    JSGlobalData* globalData = new JSGlobalData(false);
-    setDefaultIdentifierTable(globalData->identifierTable);
-    setCurrentIdentifierTable(globalData->identifierTable);
-    return adoptRef(globalData);
+    return adoptRef(new JSGlobalData(Default, type));
 }
 
 }
 
-PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
+PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(ThreadStackType type)
 {
     Structure::startIgnoringLeaks();
 {
     Structure::startIgnoringLeaks();
-    RefPtr<JSGlobalData> data = create();
+    RefPtr<JSGlobalData> data = create(type);
     Structure::stopIgnoringLeaks();
     return data.release();
 }
     Structure::stopIgnoringLeaks();
     return data.release();
 }
@@ -224,7 +248,7 @@ JSGlobalData& JSGlobalData::sharedInstance()
 {
     JSGlobalData*& instance = sharedInstanceInternal();
     if (!instance) {
 {
     JSGlobalData*& instance = sharedInstanceInternal();
     if (!instance) {
-        instance = new JSGlobalData(true);
+        instance = new JSGlobalData(APIShared, ThreadStackTypeSmall);
 #if ENABLE(JSC_MULTIPLE_THREADS)
         instance->makeUsableFromMultipleThreads();
 #endif
 #if ENABLE(JSC_MULTIPLE_THREADS)
         instance->makeUsableFromMultipleThreads();
 #endif
index 0f1f3c69ec8e34bacbf5a71d460523c732e8d3af..c0f13f8d1e7df17859e4b34fcf012b0061e83415 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef JSGlobalData_h
 #define JSGlobalData_h
 
 #ifndef JSGlobalData_h
 #define JSGlobalData_h
 
+#include "CachedTranscendentalFunction.h"
 #include "Collector.h"
 #include "DateInstanceCache.h"
 #include "ExecutableAllocator.h"
 #include "Collector.h"
 #include "DateInstanceCache.h"
 #include "ExecutableAllocator.h"
@@ -37,6 +38,7 @@
 #include "MarkStack.h"
 #include "NumericStrings.h"
 #include "SmallStrings.h"
 #include "MarkStack.h"
 #include "NumericStrings.h"
 #include "SmallStrings.h"
+#include "Terminator.h"
 #include "TimeoutChecker.h"
 #include "WeakRandom.h"
 #include <wtf/Forward.h>
 #include "TimeoutChecker.h"
 #include "WeakRandom.h"
 #include <wtf/Forward.h>
@@ -56,6 +58,7 @@ namespace JSC {
     class JSObject;
     class Lexer;
     class Parser;
     class JSObject;
     class Lexer;
     class Parser;
+    class RegExpCache;
     class Stringifier;
     class Structure;
     class UString;
     class Stringifier;
     class Structure;
     class UString;
@@ -83,18 +86,34 @@ namespace JSC {
         double increment;
     };
 
         double increment;
     };
 
+    enum ThreadStackType {
+        ThreadStackTypeLarge,
+        ThreadStackTypeSmall
+    };
+
     class JSGlobalData : public RefCounted<JSGlobalData> {
     public:
     class JSGlobalData : public RefCounted<JSGlobalData> {
     public:
+        // WebCore has a one-to-one mapping of threads to JSGlobalDatas;
+        // either create() or createLeaked() should only be called once
+        // on a thread, this is the 'default' JSGlobalData (it uses the
+        // thread's default string uniquing table from wtfThreadData).
+        // API contexts created using the new context group aware interface
+        // create APIContextGroup objects which require less locking of JSC
+        // than the old singleton APIShared JSGlobalData created for use by
+        // the original API.
+        enum GlobalDataType { Default, APIContextGroup, APIShared };
+
         struct ClientData {
             virtual ~ClientData() = 0;
         };
 
         struct ClientData {
             virtual ~ClientData() = 0;
         };
 
+        bool isSharedInstance() { return globalDataType == APIShared; }
         static bool sharedInstanceExists();
         static JSGlobalData& sharedInstance();
 
         static bool sharedInstanceExists();
         static JSGlobalData& sharedInstance();
 
-        static PassRefPtr<JSGlobalData> create();
-        static PassRefPtr<JSGlobalData> createLeaked();
-        static PassRefPtr<JSGlobalData> createNonDefault();
+        static PassRefPtr<JSGlobalData> create(ThreadStackType);
+        static PassRefPtr<JSGlobalData> createLeaked(ThreadStackType);
+        static PassRefPtr<JSGlobalData> createContextGroup(ThreadStackType);
         ~JSGlobalData();
 
 #if ENABLE(JSC_MULTIPLE_THREADS)
         ~JSGlobalData();
 
 #if ENABLE(JSC_MULTIPLE_THREADS)
@@ -102,7 +121,7 @@ namespace JSC {
         void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
 #endif
 
         void makeUsableFromMultipleThreads() { heap.makeUsableFromMultipleThreads(); }
 #endif
 
-        bool isSharedInstance;
+        GlobalDataType globalDataType;
         ClientData* clientData;
 
         const HashTable* arrayTable;
         ClientData* clientData;
 
         const HashTable* arrayTable;
@@ -116,6 +135,7 @@ namespace JSC {
         
         RefPtr<Structure> activationStructure;
         RefPtr<Structure> interruptedExecutionErrorStructure;
         
         RefPtr<Structure> activationStructure;
         RefPtr<Structure> interruptedExecutionErrorStructure;
+        RefPtr<Structure> terminatedExecutionErrorStructure;
         RefPtr<Structure> staticScopeStructure;
         RefPtr<Structure> stringStructure;
         RefPtr<Structure> notAnObjectErrorStubStructure;
         RefPtr<Structure> staticScopeStructure;
         RefPtr<Structure> stringStructure;
         RefPtr<Structure> notAnObjectErrorStubStructure;
@@ -146,13 +166,25 @@ namespace JSC {
         ExecutableAllocator executableAllocator;
 #endif
 
         ExecutableAllocator executableAllocator;
 #endif
 
+#if ENABLE(JIT)
+#if ENABLE(INTERPRETER)
+        bool canUseJIT() { return m_canUseJIT; }
+#endif
+#else
+        bool canUseJIT() { return false; }
+#endif
         Lexer* lexer;
         Parser* parser;
         Interpreter* interpreter;
 #if ENABLE(JIT)
         Lexer* lexer;
         Parser* parser;
         Interpreter* interpreter;
 #if ENABLE(JIT)
-        JITThunks jitStubs;
+        OwnPtr<JITThunks> jitStubs;
+        NativeExecutable* getThunk(ThunkGenerator generator)
+        {
+            return jitStubs->specializedThunk(this, generator);
+        }
 #endif
         TimeoutChecker timeoutChecker;
 #endif
         TimeoutChecker timeoutChecker;
+        Terminator terminator;
         Heap heap;
 
         JSValue exception;
         Heap heap;
 
         JSValue exception;
@@ -181,24 +213,32 @@ namespace JSC {
         
         UString cachedDateString;
         double cachedDateStringValue;
         
         UString cachedDateString;
         double cachedDateStringValue;
-        
-        WeakRandom weakRandom;
+
+        int maxReentryDepth;
+
+        RegExpCache* m_regExpCache;
 
 #ifndef NDEBUG
 
 #ifndef NDEBUG
-        bool mainThreadOnly;
+        ThreadIdentifier exclusiveThread;
 #endif
 
 #endif
 
+        CachedTranscendentalFunction<sin> cachedSin;
+
         void resetDateCache();
 
         void startSampling();
         void stopSampling();
         void dumpSampleData(ExecState* exec);
         void resetDateCache();
 
         void startSampling();
         void stopSampling();
         void dumpSampleData(ExecState* exec);
+        RegExpCache* regExpCache() { return m_regExpCache; }
     private:
     private:
-        JSGlobalData(bool isShared);
+        JSGlobalData(GlobalDataType, ThreadStackType);
         static JSGlobalData*& sharedInstanceInternal();
         void createNativeThunk();
         static JSGlobalData*& sharedInstanceInternal();
         void createNativeThunk();
+#if ENABLE(JIT) && ENABLE(INTERPRETER)
+        bool m_canUseJIT;
+#endif
     };
     };
-    
+
 } // namespace JSC
 
 #endif // JSGlobalData_h
 } // namespace JSC
 
 #endif // JSGlobalData_h
index 4bf0a6904c32d8a9ee4eb3d058f5d4e205330a4a..1e2522681876ded163f4dcba388242597a9d0591 100644 (file)
@@ -117,10 +117,8 @@ JSGlobalObject::~JSGlobalObject()
         (*it)->clearGlobalObject();
         
     RegisterFile& registerFile = globalData()->interpreter->registerFile();
         (*it)->clearGlobalObject();
         
     RegisterFile& registerFile = globalData()->interpreter->registerFile();
-    if (registerFile.globalObject() == this) {
-        registerFile.setGlobalObject(0);
+    if (registerFile.clearGlobalObject(this))
         registerFile.setNumGlobals(0);
         registerFile.setNumGlobals(0);
-    }
     d()->destructor(d());
 }
 
     d()->destructor(d());
 }
 
@@ -247,15 +245,6 @@ void JSGlobalObject::reset(JSValue prototype)
     ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
     d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
 
     ErrorPrototype* errorPrototype = new (exec) ErrorPrototype(exec, ErrorPrototype::createStructure(d()->objectPrototype), d()->prototypeFunctionStructure.get());
     d()->errorStructure = ErrorInstance::createStructure(errorPrototype);
 
-    RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
-
-    NativeErrorPrototype* evalErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "EvalError", "EvalError");
-    NativeErrorPrototype* rangeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "RangeError", "RangeError");
-    NativeErrorPrototype* referenceErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "ReferenceError", "ReferenceError");
-    NativeErrorPrototype* syntaxErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "SyntaxError", "SyntaxError");
-    NativeErrorPrototype* typeErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "TypeError", "TypeError");
-    NativeErrorPrototype* URIErrorPrototype = new (exec) NativeErrorPrototype(exec, nativeErrorPrototypeStructure, "URIError", "URIError");
-
     // Constructors
 
     JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get());
     // Constructors
 
     JSCell* objectConstructor = new (exec) ObjectConstructor(exec, ObjectConstructor::createStructure(d()->functionPrototype), d()->objectPrototype, d()->prototypeFunctionStructure.get());
@@ -270,14 +259,15 @@ void JSGlobalObject::reset(JSValue prototype)
 
     d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructure(d()->functionPrototype), errorPrototype);
 
 
     d()->errorConstructor = new (exec) ErrorConstructor(exec, ErrorConstructor::createStructure(d()->functionPrototype), errorPrototype);
 
+    RefPtr<Structure> nativeErrorPrototypeStructure = NativeErrorPrototype::createStructure(errorPrototype);
     RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype);
 
     RefPtr<Structure> nativeErrorStructure = NativeErrorConstructor::createStructure(d()->functionPrototype);
 
-    d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, evalErrorPrototype);
-    d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, rangeErrorPrototype);
-    d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, referenceErrorPrototype);
-    d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, syntaxErrorPrototype);
-    d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype);
-    d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype);
+    d()->evalErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "EvalError");
+    d()->rangeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "RangeError");
+    d()->referenceErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "ReferenceError");
+    d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "SyntaxError");
+    d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "TypeError");
+    d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, nativeErrorPrototypeStructure, "URIError");
 
     d()->objectPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
     d()->functionPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
 
     d()->objectPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
     d()->functionPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, functionConstructor, DontEnum);
@@ -289,13 +279,6 @@ void JSGlobalObject::reset(JSValue prototype)
     d()->regExpPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->regExpConstructor, DontEnum);
     errorPrototype->putDirectFunctionWithoutTransition(exec->propertyNames().constructor, d()->errorConstructor, 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);
-    referenceErrorPrototype->putDirect(exec->propertyNames().constructor, d()->referenceErrorConstructor, DontEnum);
-    syntaxErrorPrototype->putDirect(exec->propertyNames().constructor, d()->syntaxErrorConstructor, DontEnum);
-    typeErrorPrototype->putDirect(exec->propertyNames().constructor, d()->typeErrorConstructor, DontEnum);
-    URIErrorPrototype->putDirect(exec->propertyNames().constructor, d()->URIErrorConstructor, DontEnum);
-
     // Set global constructors
 
     // FIXME: These properties could be handled by a static hash table.
     // Set global constructors
 
     // FIXME: These properties could be handled by a static hash table.
@@ -319,9 +302,9 @@ void JSGlobalObject::reset(JSValue prototype)
     // Set global values.
     GlobalPropertyInfo staticGlobals[] = {
         GlobalPropertyInfo(Identifier(exec, "Math"), new (exec) MathObject(exec, MathObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete),
     // 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, "NaN"), jsNaN(exec), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(Identifier(exec, "Infinity"), jsNumber(exec, Inf), DontEnum | DontDelete | ReadOnly),
+        GlobalPropertyInfo(Identifier(exec, "undefined"), jsUndefined(), DontEnum | DontDelete | ReadOnly),
         GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(JSONObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete)
     };
 
         GlobalPropertyInfo(Identifier(exec, "JSON"), new (exec) JSONObject(JSONObject::createStructure(d()->objectPrototype)), DontEnum | DontDelete)
     };
 
@@ -428,7 +411,7 @@ ExecState* JSGlobalObject::globalExec()
     return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
 }
 
     return CallFrame::create(d()->globalCallFrame + RegisterFile::CallFrameHeaderSize);
 }
 
-bool JSGlobalObject::isDynamicScope() const
+bool JSGlobalObject::isDynamicScope(bool&) const
 {
     return true;
 }
 {
     return true;
 }
index bb0836256ea57065836ba114c8823b49c0a6ae01..6b9429abca97b02d2f5e620c79600a6e4b9bb08b 100644 (file)
 #include "JSArray.h"
 #include "JSGlobalData.h"
 #include "JSVariableObject.h"
 #include "JSArray.h"
 #include "JSGlobalData.h"
 #include "JSVariableObject.h"
+#include "JSWeakObjectMapRefInternal.h"
 #include "NativeFunctionWrapper.h"
 #include "NumberPrototype.h"
 #include "StringPrototype.h"
 #include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
 #include "NativeFunctionWrapper.h"
 #include "NumberPrototype.h"
 #include "StringPrototype.h"
 #include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
+#include <wtf/RandomNumber.h>
 
 namespace JSC {
 
 
 namespace JSC {
 
@@ -56,6 +58,7 @@ namespace JSC {
     class JSGlobalObject : public JSVariableObject {
     protected:
         using JSVariableObject::JSVariableObjectData;
     class JSGlobalObject : public JSVariableObject {
     protected:
         using JSVariableObject::JSVariableObjectData;
+        typedef HashSet<RefPtr<OpaqueJSWeakObjectMap> > WeakMapSet;
 
         struct JSGlobalObjectData : public JSVariableObjectData {
             // We use an explicit destructor function pointer instead of a
 
         struct JSGlobalObjectData : public JSVariableObjectData {
             // We use an explicit destructor function pointer instead of a
@@ -90,6 +93,7 @@ namespace JSC {
                 , datePrototype(0)
                 , regExpPrototype(0)
                 , methodCallDummy(0)
                 , datePrototype(0)
                 , regExpPrototype(0)
                 , methodCallDummy(0)
+                , weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
             {
             }
             
             {
             }
             
@@ -153,6 +157,8 @@ namespace JSC {
             RefPtr<JSGlobalData> globalData;
 
             HashSet<GlobalCodeBlock*> codeBlocks;
             RefPtr<JSGlobalData> globalData;
 
             HashSet<GlobalCodeBlock*> codeBlocks;
+            WeakMapSet weakMaps;
+            WeakRandom weakRandom;
         };
 
     public:
         };
 
     public:
@@ -254,7 +260,7 @@ namespace JSC {
 
         virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
 
 
         virtual bool allowsAccessFrom(const JSGlobalObject*) const { return true; }
 
-        virtual bool isDynamicScope() const;
+        virtual bool isDynamicScope(bool& requiresDynamicChecks) const;
 
         HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
 
 
         HashSet<GlobalCodeBlock*>& codeBlocks() { return d()->codeBlocks; }
 
@@ -271,6 +277,17 @@ namespace JSC {
             return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
         }
 
             return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
         }
 
+        void registerWeakMap(OpaqueJSWeakObjectMap* map)
+        {
+            d()->weakMaps.add(map);
+        }
+
+        void deregisterWeakMap(OpaqueJSWeakObjectMap* map)
+        {
+            d()->weakMaps.remove(map);
+        }
+
+        double weakRandomNumber() { return d()->weakRandom.get(); }
     protected:
 
         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
     protected:
 
         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
index 2ddc41c030533b739575e700ff84b3de3afd2198..228ed6cd87d4f5cfd3f92db70c572739ec4621f9 100644 (file)
@@ -30,6 +30,7 @@
 #include "Interpreter.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
 #include "Interpreter.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
+#include "JSStringBuilder.h"
 #include "Lexer.h"
 #include "LiteralParser.h"
 #include "Nodes.h"
 #include "Lexer.h"
 #include "LiteralParser.h"
 #include "Nodes.h"
@@ -54,27 +55,27 @@ static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEsc
 {
     UString str = args.at(0).toString(exec);
     CString cstr = str.UTF8String(true);
 {
     UString str = args.at(0).toString(exec);
     CString cstr = str.UTF8String(true);
-    if (!cstr.c_str())
+    if (!cstr.data())
         return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
 
         return throwError(exec, URIError, "String contained an illegal UTF-16 sequence.");
 
-    StringBuilder builder;
-    const char* p = cstr.c_str();
-    for (size_t k = 0; k < cstr.size(); k++, p++) {
+    JSStringBuilder builder;
+    const char* p = cstr.data();
+    for (size_t k = 0; k < cstr.length(); k++, p++) {
         char c = *p;
         if (c && strchr(doNotEscape, c))
             builder.append(c);
         else {
             char tmp[4];
             snprintf(tmp, sizeof(tmp), "%%%02X", static_cast<unsigned char>(c));
         char c = *p;
         if (c && strchr(doNotEscape, c))
             builder.append(c);
         else {
             char tmp[4];
             snprintf(tmp, sizeof(tmp), "%%%02X", static_cast<unsigned char>(c));
-            builder.append((const char*)tmp);
+            builder.append(tmp);
         }
     }
         }
     }
-    return jsString(exec, builder.release());
+    return builder.build(exec);
 }
 
 static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
 {
 }
 
 static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
 {
-    StringBuilder builder;
+    JSStringBuilder builder;
     UString str = args.at(0).toString(exec);
     int k = 0;
     int len = str.size();
     UString str = args.at(0).toString(exec);
     int k = 0;
     int len = str.size();
@@ -135,7 +136,7 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne
         k++;
         builder.append(c);
     }
         k++;
         builder.append(c);
     }
-    return jsString(exec, builder.release());
+    return builder.build(exec);
 }
 
 bool isStrWhiteSpace(UChar c)
 }
 
 bool isStrWhiteSpace(UChar c)
@@ -240,6 +241,7 @@ static double parseInt(const UString& s, int radix)
     }
 
     if (number >= mantissaOverflowLowerBound) {
     }
 
     if (number >= mantissaOverflowLowerBound) {
+        // FIXME: It is incorrect to use UString::ascii() here because it's not thread-safe.
         if (radix == 10)
             number = WTF::strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
         else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
         if (radix == 10)
             number = WTF::strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0);
         else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32)
@@ -268,6 +270,8 @@ static double parseFloat(const UString& s)
     if (length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X'))
         return 0;
 
     if (length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X'))
         return 0;
 
+    // FIXME: UString::toDouble will ignore leading ASCII spaces, but we need to ignore
+    // other StrWhiteSpaceChar values as well.
     return s.toDouble(true /*tolerant*/, false /* NaN for empty string */);
 }
 
     return s.toDouble(true /*tolerant*/, false /* NaN for empty string */);
 }
 
@@ -378,27 +382,25 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons
         "0123456789"
         "*+-./@_";
 
         "0123456789"
         "*+-./@_";
 
-    StringBuilder builder;
-    UString s;
+    JSStringBuilder builder;
     UString str = args.at(0).toString(exec);
     const UChar* c = str.data();
     UString str = args.at(0).toString(exec);
     const UChar* c = str.data();
-    for (int k = 0; k < str.size(); k++, c++) {
+    for (unsigned k = 0; k < str.size(); k++, c++) {
         int u = c[0];
         if (u > 255) {
             char tmp[7];
             snprintf(tmp, sizeof(tmp), "%%u%04X", u);
         int u = c[0];
         if (u > 255) {
             char tmp[7];
             snprintf(tmp, sizeof(tmp), "%%u%04X", u);
-            s = UString(tmp);
+            builder.append(tmp);
         } else if (u != 0 && strchr(do_not_escape, static_cast<char>(u)))
         } else if (u != 0 && strchr(do_not_escape, static_cast<char>(u)))
-            s = UString(c, 1);
+            builder.append(c, 1);
         else {
             char tmp[4];
             snprintf(tmp, sizeof(tmp), "%%%02X", u);
         else {
             char tmp[4];
             snprintf(tmp, sizeof(tmp), "%%%02X", u);
-            s = UString(tmp);
+            builder.append(tmp);
         }
         }
-        builder.append(s);
     }
 
     }
 
-    return jsString(exec, builder.release());
+    return builder.build(exec);
 }
 
 JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 }
 
 JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args)
@@ -425,14 +427,13 @@ JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, co
         builder.append(*c);
     }
 
         builder.append(*c);
     }
 
-    return jsString(exec, builder.release());
+    return jsString(exec, builder.build());
 }
 
 #ifndef NDEBUG
 JSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
 }
 
 #ifndef NDEBUG
 JSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    CStringBuffer string;
-    args.at(0).toString(exec).getCString(string);
+    CString string = args.at(0).toString(exec).UTF8String();
     puts(string.data());
     return jsUndefined();
 }
     puts(string.data());
     return jsUndefined();
 }
index 4ed35fc45e41ea317ee868007edca36cd63b7f27..9127b6a6487aa5eade537d85daf664b68c59ada2 100644 (file)
@@ -22,8 +22,6 @@
 #ifndef JSImmediate_h
 #define JSImmediate_h
 
 #ifndef JSImmediate_h
 #define JSImmediate_h
 
-#include <wtf/Platform.h>
-
 #if !USE(JSVALUE32_64)
 
 #include <wtf/Assertions.h>
 #if !USE(JSVALUE32_64)
 
 #include <wtf/Assertions.h>
@@ -138,6 +136,8 @@ namespace JSC {
         friend class JIT;
         friend class JSValue;
         friend class JSFastMath;
         friend class JIT;
         friend class JSValue;
         friend class JSFastMath;
+        friend class JSInterfaceJIT;
+        friend class SpecializedThunkJIT;
         friend JSValue jsNumber(ExecState* exec, double d);
         friend JSValue jsNumber(ExecState*, char i);
         friend JSValue jsNumber(ExecState*, unsigned char i);
         friend JSValue jsNumber(ExecState* exec, double d);
         friend JSValue jsNumber(ExecState*, char i);
         friend JSValue jsNumber(ExecState*, unsigned char i);
@@ -166,7 +166,7 @@ namespace JSC {
         // This value is 2^48, used to encode doubles such that the encoded value will begin
         // with a 16-bit pattern within the range 0x0001..0xFFFE.
         static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
         // This value is 2^48, used to encode doubles such that the encoded value will begin
         // with a 16-bit pattern within the range 0x0001..0xFFFE.
         static const intptr_t DoubleEncodeOffset = 0x1000000000000ll;
-#else
+#elif USE(JSVALUE32)
         static const intptr_t TagTypeNumber = 0x1; // bottom bit set indicates integer, this dominates the following bit
 #endif
         static const intptr_t TagBitTypeOther   = 0x2; // second bit set indicates immediate other than an integer
         static const intptr_t TagTypeNumber = 0x1; // bottom bit set indicates integer, this dominates the following bit
 #endif
         static const intptr_t TagBitTypeOther   = 0x2; // second bit set indicates immediate other than an integer
index 8f056c81748ee562b21913969152bc7894b4c0b3..a1cffbd23de29c7b0e2c8f16559c61f97dc6b62e 100644 (file)
@@ -60,7 +60,7 @@ static void setLockCount(intptr_t count)
 }
 
 JSLock::JSLock(ExecState* exec)
 }
 
 JSLock::JSLock(ExecState* exec)
-    : m_lockBehavior(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly)
+    : m_lockBehavior(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
 {
     lock(m_lockBehavior);
 }
 {
     lock(m_lockBehavior);
 }
@@ -105,12 +105,12 @@ void JSLock::unlock(JSLockBehavior lockBehavior)
 
 void JSLock::lock(ExecState* exec)
 {
 
 void JSLock::lock(ExecState* exec)
 {
-    lock(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly);
+    lock(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly);
 }
 
 void JSLock::unlock(ExecState* exec)
 {
 }
 
 void JSLock::unlock(ExecState* exec)
 {
-    unlock(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly);
+    unlock(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly);
 }
 
 bool JSLock::currentThreadIsHoldingLock()
 }
 
 bool JSLock::currentThreadIsHoldingLock()
@@ -162,7 +162,7 @@ bool JSLock::currentThreadIsHoldingLock()
 static unsigned lockDropDepth = 0;
 
 JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
 static unsigned lockDropDepth = 0;
 
 JSLock::DropAllLocks::DropAllLocks(ExecState* exec)
-    : m_lockBehavior(exec->globalData().isSharedInstance ? LockForReal : SilenceAssertionsOnly)
+    : m_lockBehavior(exec->globalData().isSharedInstance() ? LockForReal : SilenceAssertionsOnly)
 {
     pthread_once(&createJSLockCountOnce, createJSLockCount);
 
 {
     pthread_once(&createJSLockCountOnce, createJSLockCount);
 
index f1009b9c010983f9d9530b5ec0b34d73b20a51ef..a61c75102399eea7bc5b19bb737f6ae2c902eaf5 100644 (file)
@@ -57,11 +57,6 @@ UString JSNumberCell::toString(ExecState*) const
     return UString::from(m_value);
 }
 
     return UString::from(m_value);
 }
 
-UString JSNumberCell::toThisString(ExecState*) const
-{
-    return UString::from(m_value);
-}
-
 JSObject* JSNumberCell::toObject(ExecState* exec) const
 {
     return constructNumber(exec, const_cast<JSNumberCell*>(this));
 JSObject* JSNumberCell::toObject(ExecState* exec) const
 {
     return constructNumber(exec, const_cast<JSNumberCell*>(this));
index bcb506b97394016e86030eb0da05df207373813d..cdd2d8ca5a486e992d88d16832f0651aadf1a93c 100644 (file)
@@ -62,7 +62,6 @@ namespace JSC {
         virtual UString toString(ExecState*) const;
         virtual JSObject* toObject(ExecState*) const;
 
         virtual UString toString(ExecState*) const;
         virtual JSObject* toObject(ExecState*) const;
 
-        virtual UString toThisString(ExecState*) const;
         virtual JSObject* toThisObject(ExecState*) const;
         virtual JSValue getJSNumber();
 
         virtual JSObject* toThisObject(ExecState*) const;
         virtual JSValue getJSNumber();
 
index ce0dcffe0569565fe78a3d01d4113dda68627a5d..f6c6b5f9a7260aa39f5d9a840b66c6c61b951fe8 100644 (file)
@@ -31,6 +31,7 @@
 #include "ExceptionHelpers.h"
 #include "JSArray.h"
 #include "LiteralParser.h"
 #include "ExceptionHelpers.h"
 #include "JSArray.h"
 #include "LiteralParser.h"
+#include "Lookup.h"
 #include "PropertyNameArray.h"
 #include "StringBuilder.h"
 #include <wtf/MathExtras.h>
 #include "PropertyNameArray.h"
 #include "StringBuilder.h"
 #include <wtf/MathExtras.h>
@@ -135,7 +136,7 @@ static inline JSValue unwrapBoxedPrimitive(ExecState* exec, JSValue value)
 
 static inline UString gap(ExecState* exec, JSValue space)
 {
 
 static inline UString gap(ExecState* exec, JSValue space)
 {
-    const int maxGapLength = 10;
+    const unsigned maxGapLength = 10;
     space = unwrapBoxedPrimitive(exec, space);
 
     // If the space value is a number, create a gap string with that number of spaces.
     space = unwrapBoxedPrimitive(exec, space);
 
     // If the space value is a number, create a gap string with that number of spaces.
@@ -268,7 +269,7 @@ JSValue Stringifier::stringify(JSValue value)
     if (m_exec->hadException())
         return jsNull();
 
     if (m_exec->hadException())
         return jsNull();
 
-    return jsString(m_exec, result.release());
+    return jsString(m_exec, result.build());
 }
 
 void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
 }
 
 void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
@@ -456,7 +457,7 @@ inline bool Stringifier::willIndent() const
 inline void Stringifier::indent()
 {
     // Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent.
 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();
+    unsigned newSize = m_indent.size() + m_gap.size();
     if (newSize > m_repeatedGap.size())
         m_repeatedGap = makeString(m_repeatedGap, m_gap);
     ASSERT(newSize <= m_repeatedGap.size());
     if (newSize > m_repeatedGap.size())
         m_repeatedGap = makeString(m_repeatedGap, m_gap);
     ASSERT(newSize <= m_repeatedGap.size());
@@ -868,4 +869,12 @@ JSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec, JSObject*, JSValue
     return Stringifier(exec, replacer, space).stringify(value);
 }
 
     return Stringifier(exec, replacer, space).stringify(value);
 }
 
+UString JSONStringify(ExecState* exec, JSValue value, unsigned indent)
+{
+    JSValue result = Stringifier(exec, jsNull(), jsNumber(exec, indent)).stringify(value);
+    if (result.isUndefinedOrNull())
+        return UString();
+    return result.getString(exec);
+}
+
 } // namespace JSC
 } // namespace JSC
index 905e4bc0e0e21cd5f4ee1104b756688430f5e10b..7a9e0a48b90e035647b9686e053245a1325240c5 100644 (file)
@@ -57,6 +57,8 @@ namespace JSC {
         static const ClassInfo info;
     };
 
         static const ClassInfo info;
     };
 
+    UString JSONStringify(ExecState* exec, JSValue value, unsigned indent);
+
 } // namespace JSC
 
 #endif // JSONObject_h
 } // namespace JSC
 
 #endif // JSONObject_h
index d9500aa5a98d376122f026a00217c831ff602c2f..61d3bb145767b676a9a0aa280fbcfec663c96b78 100644 (file)
@@ -516,9 +516,12 @@ void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunct
 
 NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location)
 {
 
 NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue* location)
 {
-    if (JSObject* getterFunction = asGetterSetter(*location)->getter())
-        slot.setGetterSlot(getterFunction);
-    else
+    if (JSObject* getterFunction = asGetterSetter(*location)->getter()) {
+        if (!structure()->isDictionary())
+            slot.setCacheableGetterSlot(this, getterFunction, offsetForLocation(location));
+        else
+            slot.setGetterSlot(getterFunction);
+    } else
         slot.setUndefined();
 }
 
         slot.setUndefined();
 }
 
index 2b31a65994a0c334ff12e70ea3e4064b698c9f10..6824c23fea7c39a79aa1e518febfaaf724ea73e4 100644 (file)
@@ -26,6 +26,7 @@
 #include "ArgList.h"
 #include "ClassInfo.h"
 #include "CommonIdentifiers.h"
 #include "ArgList.h"
 #include "ClassInfo.h"
 #include "CommonIdentifiers.h"
+#include "Completion.h"
 #include "CallFrame.h"
 #include "JSCell.h"
 #include "JSNumberCell.h"
 #include "CallFrame.h"
 #include "JSCell.h"
 #include "JSNumberCell.h"
@@ -35,6 +36,7 @@
 #include "ScopeChain.h"
 #include "Structure.h"
 #include "JSGlobalData.h"
 #include "ScopeChain.h"
 #include "Structure.h"
 #include "JSGlobalData.h"
+#include "JSString.h"
 #include <wtf/StdLibExtras.h>
 
 namespace JSC {
 #include <wtf/StdLibExtras.h>
 
 namespace JSC {
@@ -170,6 +172,7 @@ namespace JSC {
 
         void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
         void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0);
 
         void putDirect(const Identifier& propertyName, JSValue value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
         void putDirect(const Identifier& propertyName, JSValue value, unsigned attr = 0);
+        void putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot&);
 
         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(const Identifier& propertyName, JSCell* value, unsigned attr = 0);
         void putDirectFunction(const Identifier& propertyName, JSCell* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
@@ -194,9 +197,10 @@ namespace JSC {
         virtual bool isGlobalObject() const { return false; }
         virtual bool isVariableObject() const { return false; }
         virtual bool isActivationObject() const { return false; }
         virtual bool isGlobalObject() const { return false; }
         virtual bool isVariableObject() const { return false; }
         virtual bool isActivationObject() const { return false; }
-        virtual bool isWatchdogException() const { return false; }
         virtual bool isNotAnObjectErrorStub() const { return false; }
 
         virtual bool isNotAnObjectErrorStub() const { return false; }
 
+        virtual ComplType exceptionType() const { return Throw; }
+
         void allocatePropertyStorage(size_t oldSize, size_t newSize);
         void allocatePropertyStorageInline(size_t oldSize, size_t newSize);
         bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
         void allocatePropertyStorage(size_t oldSize, size_t newSize);
         void allocatePropertyStorageInline(size_t oldSize, size_t newSize);
         bool isUsingInlineStorage() const { return m_structure->isUsingInlineStorage(); }
@@ -436,12 +440,20 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
         JSCell* currentSpecificFunction;
         size_t offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
         if (offset != WTF::notFound) {
         JSCell* currentSpecificFunction;
         size_t offset = m_structure->get(propertyName, currentAttributes, currentSpecificFunction);
         if (offset != WTF::notFound) {
+            // If there is currently a specific function, and there now either isn't,
+            // or the new value is different, then despecify.
             if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
                 m_structure->despecifyDictionaryFunction(propertyName);
             if (checkReadOnly && currentAttributes & ReadOnly)
                 return;
             putDirectOffset(offset, value);
             if (currentSpecificFunction && (specificFunction != currentSpecificFunction))
                 m_structure->despecifyDictionaryFunction(propertyName);
             if (checkReadOnly && currentAttributes & ReadOnly)
                 return;
             putDirectOffset(offset, value);
-            if (!specificFunction && !currentSpecificFunction)
+            // At this point, the objects structure only has a specific value set if previously there
+            // had been one set, and if the new value being specified is the same (otherwise we would
+            // have despecified, above).  So, if currentSpecificFunction is not set, or if the new
+            // value is different (or there is no new value), then the slot now has no value - and
+            // as such it is cachable.
+            // If there was previously a value, and the new value is the same, then we cannot cache.
+            if (!currentSpecificFunction || (specificFunction != currentSpecificFunction))
                 slot.setExistingProperty(this, offset);
             return;
         }
                 slot.setExistingProperty(this, offset);
             return;
         }
@@ -468,7 +480,8 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
         ASSERT(offset < structure->propertyStorageCapacity());
         setStructure(structure.release());
         putDirectOffset(offset, value);
         ASSERT(offset < structure->propertyStorageCapacity());
         setStructure(structure.release());
         putDirectOffset(offset, value);
-        // See comment on setNewProperty call below.
+        // This is a new property; transitions with specific values are not currently cachable,
+        // so leave the slot in an uncachable state.
         if (!specificFunction)
             slot.setNewProperty(this, offset);
         return;
         if (!specificFunction)
             slot.setNewProperty(this, offset);
         return;
@@ -481,14 +494,28 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
         if (checkReadOnly && currentAttributes & ReadOnly)
             return;
 
         if (checkReadOnly && currentAttributes & ReadOnly)
             return;
 
-        if (currentSpecificFunction && (specificFunction != currentSpecificFunction)) {
+        // There are three possibilities here:
+        //  (1) There is an existing specific value set, and we're overwriting with *the same value*.
+        //       * Do nothing - no need to despecify, but that means we can't cache (a cached
+        //         put could write a different value). Leave the slot in an uncachable state.
+        //  (2) There is a specific value currently set, but we're writing a different value.
+        //       * First, we have to despecify.  Having done so, this is now a regular slot
+        //         with no specific value, so go ahead & cache like normal.
+        //  (3) Normal case, there is no specific value set.
+        //       * Go ahead & cache like normal.
+        if (currentSpecificFunction) {
+            // case (1) Do the put, then return leaving the slot uncachable.
+            if (specificFunction == currentSpecificFunction) {
+                putDirectOffset(offset, value);
+                return;
+            }
+            // case (2) Despecify, fall through to (3).
             setStructure(Structure::despecifyFunctionTransition(m_structure, propertyName));
             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);
+
+        // case (3) set the slot, do the put, return.
         slot.setExistingProperty(this, offset);
         slot.setExistingProperty(this, offset);
+        putDirectOffset(offset, value);
         return;
     }
 
         return;
     }
 
@@ -510,7 +537,8 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
     ASSERT(offset < structure->propertyStorageCapacity());
     setStructure(structure.release());
     putDirectOffset(offset, value);
     ASSERT(offset < structure->propertyStorageCapacity());
     setStructure(structure.release());
     putDirectOffset(offset, value);
-    // Function transitions are not currently cachable, so leave the slot in an uncachable state.
+    // This is a new property; transitions with specific values are not currently cachable,
+    // so leave the slot in an uncachable state.
     if (!specificFunction)
         slot.setNewProperty(this, offset);
 }
     if (!specificFunction)
         slot.setNewProperty(this, offset);
 }
@@ -543,6 +571,11 @@ inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, u
     putDirectInternal(propertyName, value, attributes, false, slot, 0);
 }
 
     putDirectInternal(propertyName, value, attributes, false, slot, 0);
 }
 
+inline void JSObject::putDirect(const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+{
+    putDirectInternal(propertyName, value, 0, 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 attributes, bool checkReadOnly, PutPropertySlot& slot)
 {
     putDirectInternal(propertyName, value, attributes, checkReadOnly, slot, value);
@@ -645,6 +678,12 @@ inline void JSValue::put(ExecState* exec, const Identifier& propertyName, JSValu
     asCell()->put(exec, propertyName, value, slot);
 }
 
     asCell()->put(exec, propertyName, value, slot);
 }
 
+inline void JSValue::putDirect(ExecState*, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+{
+    ASSERT(isCell() && isObject());
+    asObject(asCell())->putDirect(propertyName, value, slot);
+}
+
 inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
 {
     if (UNLIKELY(!isCell())) {
 inline void JSValue::put(ExecState* exec, unsigned propertyName, JSValue value)
 {
     if (UNLIKELY(!isCell())) {
@@ -685,6 +724,18 @@ ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
     markStack.appendValues(reinterpret_cast<JSValue*>(storage), storageSize);
 }
 
     markStack.appendValues(reinterpret_cast<JSValue*>(storage), storageSize);
 }
 
+// --- JSValue inlines ----------------------------
+
+ALWAYS_INLINE UString JSValue::toThisString(ExecState* exec) const
+{
+    return isString() ? static_cast<JSString*>(asCell())->value(exec) : toThisObject(exec)->toString(exec);
+}
+
+inline JSString* JSValue::toThisJSString(ExecState* exec) const
+{
+    return isString() ? static_cast<JSString*>(asCell()) : jsString(exec, toThisObject(exec)->toString(exec));
+}
+
 } // namespace JSC
 
 #endif // JSObject_h
 } // namespace JSC
 
 #endif // JSObject_h
index 3f533a0bf0b7b4cd64649bee9994f5549969a0c1..01700ac212155b4fe9b97faaad1bfdcc74042ffa 100644 (file)
@@ -67,8 +67,13 @@ namespace JSC {
         JSValue get(ExecState*, JSObject*, size_t i);
         size_t size() { return m_jsStringsSize; }
 
         JSValue get(ExecState*, JSObject*, size_t i);
         size_t size() { return m_jsStringsSize; }
 
-        void setCachedStructure(Structure* structure) { m_cachedStructure = structure; }
-        Structure* cachedStructure() { return m_cachedStructure; }
+        void setCachedStructure(Structure* structure)
+        {
+            ASSERT(!m_cachedStructure);
+            ASSERT(structure);
+            m_cachedStructure = structure;
+        }
+        Structure* cachedStructure() { return m_cachedStructure.get(); }
 
         void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
         StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
 
         void setCachedPrototypeChain(NonNullPassRefPtr<StructureChain> cachedPrototypeChain) { m_cachedPrototypeChain = cachedPrototypeChain; }
         StructureChain* cachedPrototypeChain() { return m_cachedPrototypeChain.get(); }
@@ -76,7 +81,7 @@ namespace JSC {
     private:
         JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
 
     private:
         JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
 
-        Structure* m_cachedStructure;
+        RefPtr<Structure> m_cachedStructure;
         RefPtr<StructureChain> m_cachedPrototypeChain;
         uint32_t m_numCacheableSlots;
         uint32_t m_jsStringsSize;
         RefPtr<StructureChain> m_cachedPrototypeChain;
         uint32_t m_numCacheableSlots;
         uint32_t m_jsStringsSize;
index a877ec648c1e45d04c72f38d5f3e26ff578139e5..ad1021809386f695e7e22538aa3edf36598384d3 100644 (file)
@@ -58,7 +58,7 @@ void JSStaticScopeObject::putWithAttributes(ExecState*, const Identifier& proper
     ASSERT_NOT_REACHED();
 }
 
     ASSERT_NOT_REACHED();
 }
 
-bool JSStaticScopeObject::isDynamicScope() const
+bool JSStaticScopeObject::isDynamicScope(bool&) const
 {
     return false;
 }
 {
     return false;
 }
index 4d156d4756e3d741578a6da6872771f176ac31b0..dcece9d97346c6e32f49060fdcaf888e98da50e8 100644 (file)
@@ -51,7 +51,7 @@ namespace JSC{
         }
         virtual ~JSStaticScopeObject();
         virtual void markChildren(MarkStack&);
         }
         virtual ~JSStaticScopeObject();
         virtual void markChildren(MarkStack&);
-        bool isDynamicScope() const;
+        bool isDynamicScope(bool& requiresDynamicChecks) const;
         virtual JSObject* toThisObject(ExecState*) const;
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
         virtual JSObject* toThisObject(ExecState*) const;
         virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&);
         virtual void put(ExecState*, const Identifier&, JSValue, PutPropertySlot&);
index 1e23a15f7565288f202d7a3a2861c80dd7540f16..1d5e639714f5f47811390be4d7bdeb8030936b8e 100644 (file)
 
 namespace JSC {
 
 
 namespace JSC {
 
-void JSString::Rope::destructNonRecursive()
-{
-    Vector<Rope*, 32> workQueue;
-    Rope* rope = this;
-
-    while (true) {
-        unsigned length = rope->ropeLength();
-        for (unsigned i = 0; i < length; ++i) {
-            Fiber& fiber = rope->fibers(i);
-            if (fiber.isString())
-                fiber.string()->deref();
-            else {
-                Rope* nextRope = fiber.rope();
-                if (nextRope->hasOneRef())
-                    workQueue.append(nextRope);
-                else
-                    nextRope->deref();
-            }
-        }
-        if (rope != this)
-            fastFree(rope);
-
-        if (workQueue.isEmpty())
-            return;
-
-        rope = workQueue.last();
-        workQueue.removeLast();
-    }
-}
-
-JSString::Rope::~Rope()
-{
-    destructNonRecursive();
-}
-
 // Overview: this methods converts a JSString from holding a string in rope form
 // down to a simple UString representation.  It does so by building up the string
 // backwards, since we want to avoid recursion, we expect that the tree structure
 // representing the rope is likely imbalanced with more nodes down the left side
 // (since appending to the string is likely more common) - and as such resolving
 // in this fashion should minimize work queue size.  (If we built the queue forwards
 // Overview: this methods converts a JSString from holding a string in rope form
 // down to a simple UString representation.  It does so by building up the string
 // backwards, since we want to avoid recursion, we expect that the tree structure
 // representing the rope is likely imbalanced with more nodes down the left side
 // (since appending to the string is likely more common) - and as such resolving
 // in this fashion should minimize work queue size.  (If we built the queue forwards
-// we would likely have to place all of the constituent UString::Reps into the
+// we would likely have to place all of the constituent UStringImpls into the
 // Vector before performing any concatenation, but by working backwards we likely
 // only fill the queue with the number of substrings at any given level in a
 // rope-of-ropes.)
 // Vector before performing any concatenation, but by working backwards we likely
 // only fill the queue with the number of substrings at any given level in a
 // rope-of-ropes.)
@@ -82,51 +47,52 @@ void JSString::resolveRope(ExecState* exec) const
 
     // Allocate the buffer to hold the final string, position initially points to the end.
     UChar* buffer;
 
     // Allocate the buffer to hold the final string, position initially points to the end.
     UChar* buffer;
-    if (PassRefPtr<UStringImpl> newImpl = UStringImpl::tryCreateUninitialized(m_stringLength, buffer))
+    if (PassRefPtr<UStringImpl> newImpl = UStringImpl::tryCreateUninitialized(m_length, buffer))
         m_value = newImpl;
     else {
         m_value = newImpl;
     else {
-        for (unsigned i = 0; i < m_ropeLength; ++i) {
-            m_fibers[i].deref();
-            m_fibers[i] = static_cast<void*>(0);
+        for (unsigned i = 0; i < m_fiberCount; ++i) {
+            RopeImpl::deref(m_other.m_fibers[i]);
+            m_other.m_fibers[i] = 0;
         }
         }
-        m_ropeLength = 0;
+        m_fiberCount = 0;
         ASSERT(!isRope());
         ASSERT(m_value == UString());
         ASSERT(!isRope());
         ASSERT(m_value == UString());
-        throwOutOfMemoryError(exec);
+        if (exec)
+            throwOutOfMemoryError(exec);
         return;
     }
         return;
     }
-    UChar* position = buffer + m_stringLength;
-
-    // Start with the current Rope.
-    Vector<Rope::Fiber, 32> workQueue;
-    Rope::Fiber currentFiber;
-    for (unsigned i = 0; i < (m_ropeLength - 1); ++i)
-        workQueue.append(m_fibers[i]);
-    currentFiber = m_fibers[m_ropeLength - 1];
+    UChar* position = buffer + m_length;
+
+    // Start with the current RopeImpl.
+    Vector<RopeImpl::Fiber, 32> workQueue;
+    RopeImpl::Fiber currentFiber;
+    for (unsigned i = 0; i < (m_fiberCount - 1); ++i)
+        workQueue.append(m_other.m_fibers[i]);
+    currentFiber = m_other.m_fibers[m_fiberCount - 1];
     while (true) {
     while (true) {
-        if (currentFiber.isRope()) {
-            Rope* rope = currentFiber.rope();
+        if (RopeImpl::isRope(currentFiber)) {
+            RopeImpl* rope = static_cast<RopeImpl*>(currentFiber);
             // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber'
             // (we will be working backwards over the rope).
             // Copy the contents of the current rope into the workQueue, with the last item in 'currentFiber'
             // (we will be working backwards over the rope).
-            unsigned ropeLengthMinusOne = rope->ropeLength() - 1;
-            for (unsigned i = 0; i < ropeLengthMinusOne; ++i)
-                workQueue.append(rope->fibers(i));
-            currentFiber = rope->fibers(ropeLengthMinusOne);
+            unsigned fiberCountMinusOne = rope->fiberCount() - 1;
+            for (unsigned i = 0; i < fiberCountMinusOne; ++i)
+                workQueue.append(rope->fibers()[i]);
+            currentFiber = rope->fibers()[fiberCountMinusOne];
         } else {
         } else {
-            UString::Rep* string = currentFiber.string();
-            unsigned length = string->size();
+            UStringImpl* string = static_cast<UStringImpl*>(currentFiber);
+            unsigned length = string->length();
             position -= length;
             position -= length;
-            UStringImpl::copyChars(position, string->data(), length);
+            UStringImpl::copyChars(position, string->characters(), length);
 
             // Was this the last item in the work queue?
             if (workQueue.isEmpty()) {
                 // Create a string from the UChar buffer, clear the rope RefPtr.
                 ASSERT(buffer == position);
 
             // Was this the last item in the work queue?
             if (workQueue.isEmpty()) {
                 // Create a string from the UChar buffer, clear the rope RefPtr.
                 ASSERT(buffer == position);
-                for (unsigned i = 0; i < m_ropeLength; ++i) {
-                    m_fibers[i].deref();
-                    m_fibers[i] = static_cast<void*>(0);
+                for (unsigned i = 0; i < m_fiberCount; ++i) {
+                    RopeImpl::deref(m_other.m_fibers[i]);
+                    m_other.m_fibers[i] = 0;
                 }
                 }
-                m_ropeLength = 0;
+                m_fiberCount = 0;
 
                 ASSERT(!isRope());
                 return;
 
                 ASSERT(!isRope());
                 return;
@@ -139,6 +105,70 @@ void JSString::resolveRope(ExecState* exec) const
     }
 }
 
     }
 }
 
+JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UString& replacement)
+{
+    if (!isRope()) {
+        unsigned matchPosition = m_value.find(character);
+        if (matchPosition == UString::NotFound)
+            return JSValue(this);
+        return jsString(exec, m_value.substr(0, matchPosition), replacement, m_value.substr(matchPosition + 1));
+    }
+
+    RopeIterator end;
+    
+    // Count total fibers and find matching string.
+    size_t fiberCount = 0;
+    UStringImpl* matchString = 0;
+    int matchPosition = -1;
+    for (RopeIterator it(m_other.m_fibers, m_fiberCount); it != end; ++it) {
+        ++fiberCount;
+        if (matchString)
+            continue;
+
+        UStringImpl* string = *it;
+        matchPosition = string->find(character);
+        if (matchPosition == -1)
+            continue;
+        matchString = string;
+    }
+
+    if (!matchString)
+        return this;
+
+    RopeBuilder builder(replacement.size() ? fiberCount + 2 : fiberCount + 1);
+    if (UNLIKELY(builder.isOutOfMemory()))
+        return throwOutOfMemoryError(exec);
+
+    for (RopeIterator it(m_other.m_fibers, m_fiberCount); it != end; ++it) {
+        UStringImpl* string = *it;
+        if (string != matchString) {
+            builder.append(UString(string));
+            continue;
+        }
+
+        builder.append(UString(string).substr(0, matchPosition));
+        if (replacement.size())
+            builder.append(replacement);
+        builder.append(UString(string).substr(matchPosition + 1));
+        matchString = 0;
+    }
+
+    JSGlobalData* globalData = &exec->globalData();
+    return JSValue(new (globalData) JSString(globalData, builder.release()));
+}
+
+JSString* JSString::getIndexSlowCase(ExecState* exec, unsigned i)
+{
+    ASSERT(isRope());
+    resolveRope(exec);
+    // Return a safe no-value result, this should never be used, since the excetion will be thrown.
+    if (exec->exception())
+        return jsString(exec, "");
+    ASSERT(!isRope());
+    ASSERT(i < m_value.size());
+    return jsSingleCharacterSubstring(exec, m_value, i);
+}
+
 JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     return const_cast<JSString*>(this);
 JSValue JSString::toPrimitive(ExecState*, PreferredPrimitiveType) const
 {
     return const_cast<JSString*>(this);
@@ -153,7 +183,7 @@ bool JSString::getPrimitiveNumber(ExecState* exec, double& number, JSValue& resu
 
 bool JSString::toBoolean(ExecState*) const
 {
 
 bool JSString::toBoolean(ExecState*) const
 {
-    return m_stringLength;
+    return m_length;
 }
 
 double JSString::toNumber(ExecState* exec) const
 }
 
 double JSString::toNumber(ExecState* exec) const
@@ -166,16 +196,6 @@ UString JSString::toString(ExecState* exec) const
     return value(exec);
 }
 
     return value(exec);
 }
 
-UString JSString::toThisString(ExecState* exec) const
-{
-    return value(exec);
-}
-
-JSString* JSString::toThisJSString(ExecState*)
-{
-    return this;
-}
-
 inline StringObject* StringObject::create(ExecState* exec, JSString* string)
 {
     return new (exec) StringObject(exec->lexicalGlobalObject()->stringObjectStructure(), string);
 inline StringObject* StringObject::create(ExecState* exec, JSString* string)
 {
     return new (exec) StringObject(exec->lexicalGlobalObject()->stringObjectStructure(), string);
@@ -215,14 +235,14 @@ bool JSString::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNam
 bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
 {
     if (propertyName == exec->propertyNames().length) {
 bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
 {
     if (propertyName == exec->propertyNames().length) {
-        descriptor.setDescriptor(jsNumber(exec, m_stringLength), DontEnum | DontDelete | ReadOnly);
+        descriptor.setDescriptor(jsNumber(exec, m_length), DontEnum | DontDelete | ReadOnly);
         return true;
     }
     
     bool isStrictUInt32;
     unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
         return true;
     }
     
     bool isStrictUInt32;
     unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
-    if (isStrictUInt32 && i < m_stringLength) {
-        descriptor.setDescriptor(jsSingleCharacterSubstring(exec, value(exec), i), DontDelete | ReadOnly);
+    if (isStrictUInt32 && i < m_length) {
+        descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly);
         return true;
     }
     
         return true;
     }
     
index af03025170e0e743bd4e1f671736eab4119362bf..dec925d4b5667752da2e0a1fd3ccb2234d2cdb7b 100644 (file)
@@ -29,6 +29,7 @@
 #include "JSNumberCell.h"
 #include "PropertyDescriptor.h"
 #include "PropertySlot.h"
 #include "JSNumberCell.h"
 #include "PropertyDescriptor.h"
 #include "PropertySlot.h"
+#include "RopeImpl.h"
 
 namespace JSC {
 
 
 namespace JSC {
 
@@ -41,7 +42,6 @@ namespace JSC {
 
     JSString* jsSingleCharacterString(JSGlobalData*, UChar);
     JSString* jsSingleCharacterString(ExecState*, UChar);
 
     JSString* jsSingleCharacterString(JSGlobalData*, UChar);
     JSString* jsSingleCharacterString(ExecState*, UChar);
-    JSString* jsSingleCharacterSubstring(JSGlobalData*, const UString&, unsigned offset);
     JSString* jsSingleCharacterSubstring(ExecState*, const UString&, unsigned offset);
     JSString* jsSubstring(JSGlobalData*, const UString&, unsigned offset, unsigned length);
     JSString* jsSubstring(ExecState*, const UString&, unsigned offset, unsigned length);
     JSString* jsSingleCharacterSubstring(ExecState*, const UString&, unsigned offset);
     JSString* jsSubstring(JSGlobalData*, const UString&, unsigned offset, unsigned length);
     JSString* jsSubstring(ExecState*, const UString&, unsigned offset, unsigned length);
@@ -66,183 +66,205 @@ namespace JSC {
     public:
         friend class JIT;
         friend class JSGlobalData;
     public:
         friend class JIT;
         friend class JSGlobalData;
+        friend class SpecializedThunkJIT;
+        friend struct ThunkHelpers;
 
 
-        // A Rope is a string composed of a set of substrings.
-        class Rope : public RefCounted<Rope> {
+        class RopeBuilder {
         public:
         public:
-            // A Rope is composed from a set of smaller strings called Fibers.
-            // Each Fiber in a rope is either UString::Rep or another Rope.
-            class Fiber {
-            public:
-                Fiber() : m_value(0) {}
-                Fiber(UString::Rep* string) : m_value(reinterpret_cast<intptr_t>(string)) {}
-                Fiber(Rope* rope) : m_value(reinterpret_cast<intptr_t>(rope) | 1) {}
+            RopeBuilder(unsigned fiberCount)
+                : m_index(0)
+                , m_rope(RopeImpl::tryCreateUninitialized(fiberCount))
+            {
+            }
+
+            bool isOutOfMemory() { return !m_rope; }
+
+            void append(RopeImpl::Fiber& fiber)
+            {
+                ASSERT(m_rope);
+                m_rope->initializeFiber(m_index, fiber);
+            }
+            void append(const UString& string)
+            {
+                ASSERT(m_rope);
+                m_rope->initializeFiber(m_index, string.rep());
+            }
+            void append(JSString* jsString)
+            {
+                if (jsString->isRope()) {
+                    for (unsigned i = 0; i < jsString->m_fiberCount; ++i)
+                        append(jsString->m_other.m_fibers[i]);
+                } else
+                    append(jsString->string());
+            }
+
+            PassRefPtr<RopeImpl> release()
+            {
+                ASSERT(m_index == m_rope->fiberCount());
+                return m_rope.release();
+            }
 
 
-                Fiber(void* nonFiber) : m_value(reinterpret_cast<intptr_t>(nonFiber)) {}
+            unsigned length() { return m_rope->length(); }
 
 
-                void deref()
+        private:
+            unsigned m_index;
+            RefPtr<RopeImpl> m_rope;
+        };
+
+        class RopeIterator {
+            public:
+                RopeIterator() { }
+
+                RopeIterator(RopeImpl::Fiber* fibers, size_t fiberCount)
                 {
                 {
-                    if (isRope())
-                        rope()->deref();
-                    else
-                        string()->deref();
+                    ASSERT(fiberCount);
+                    m_workQueue.append(WorkItem(fibers, fiberCount));
+                    skipRopes();
                 }
 
                 }
 
-                Fiber& ref()
+                RopeIterator& operator++()
                 {
                 {
-                    if (isString())
-                        string()->ref();
-                    else
-                        rope()->ref();
+                    WorkItem& item = m_workQueue.last();
+                    ASSERT(!RopeImpl::isRope(item.fibers[item.i]));
+                    if (++item.i == item.fiberCount)
+                        m_workQueue.removeLast();
+                    skipRopes();
                     return *this;
                 }
 
                     return *this;
                 }
 
-                unsigned refAndGetLength()
+                UStringImpl* operator*()
                 {
                 {
-                    if (isString()) {
-                        UString::Rep* rep = string();
-                        return rep->ref()->size();
-                    } else {
-                        Rope* r = rope();
-                        r->ref();
-                        return r->stringLength();
-                    }
+                    WorkItem& item = m_workQueue.last();
+                    RopeImpl::Fiber fiber = item.fibers[item.i];
+                    ASSERT(!RopeImpl::isRope(fiber));
+                    return static_cast<UStringImpl*>(fiber);
                 }
 
                 }
 
-                bool isRope() { return m_value & 1; }
-                Rope* rope() { return reinterpret_cast<Rope*>(m_value & ~1); }
-                bool isString() { return !isRope(); }
-                UString::Rep* string() { return reinterpret_cast<UString::Rep*>(m_value); }
+                bool operator!=(const RopeIterator& other) const
+                {
+                    return m_workQueue != other.m_workQueue;
+                }
 
 
-                void* nonFiber() { return reinterpret_cast<void*>(m_value); }
             private:
             private:
-                intptr_t m_value;
-            };
-
-            // Creates a Rope comprising of 'ropeLength' Fibers.
-            // The Rope is constructed in an uninitialized state - initialize must be called for each Fiber in the Rope.
-            static PassRefPtr<Rope> createOrNull(unsigned ropeLength)
-            {
-                void* allocation;
-                if (tryFastMalloc(sizeof(Rope) + (ropeLength - 1) * sizeof(Fiber)).getValue(allocation))
-                    return adoptRef(new (allocation) Rope(ropeLength));
-                return 0;
-            }
+                struct WorkItem {
+                    WorkItem(RopeImpl::Fiber* fibers, size_t fiberCount)
+                        : fibers(fibers)
+                        , fiberCount(fiberCount)
+                        , i(0)
+                    {
+                    }
 
 
-            ~Rope();
-            void destructNonRecursive();
+                    bool operator!=(const WorkItem& other) const
+                    {
+                        return fibers != other.fibers || fiberCount != other.fiberCount || i != other.i;
+                    }
 
 
-            void append(unsigned &index, Fiber& fiber)
-            {
-                m_fibers[index++] = fiber;
-                m_stringLength += fiber.refAndGetLength();
-            }
-            void append(unsigned &index, const UString& string)
-            {
-                UString::Rep* rep = string.rep();
-                m_fibers[index++] = Fiber(rep);
-                m_stringLength += rep->ref()->size();
-            }
-            void append(unsigned& index, JSString* jsString)
-            {
-                if (jsString->isRope()) {
-                    for (unsigned i = 0; i < jsString->m_ropeLength; ++i)
-                        append(index, jsString->m_fibers[i]);
-                } else
-                    append(index, jsString->string());
-            }
+                    RopeImpl::Fiber* fibers;
+                    size_t fiberCount;
+                    size_t i;
+                };
 
 
-            unsigned ropeLength() { return m_ropeLength; }
-            unsigned stringLength() { return m_stringLength; }
-            Fiber& fibers(unsigned index) { return m_fibers[index]; }
+                void skipRopes()
+                {
+                    if (m_workQueue.isEmpty())
+                        return;
+
+                    while (1) {
+                        WorkItem& item = m_workQueue.last();
+                        RopeImpl::Fiber fiber = item.fibers[item.i];
+                        if (!RopeImpl::isRope(fiber))
+                            break;
+                        RopeImpl* rope = static_cast<RopeImpl*>(fiber);
+                        if (++item.i == item.fiberCount)
+                            m_workQueue.removeLast();
+                        m_workQueue.append(WorkItem(rope->fibers(), rope->fiberCount()));
+                    }
+                }
 
 
-        private:
-            Rope(unsigned ropeLength) : m_ropeLength(ropeLength), m_stringLength(0) {}
-            void* operator new(size_t, void* inPlace) { return inPlace; }
-            
-            unsigned m_ropeLength;
-            unsigned m_stringLength;
-            Fiber m_fibers[1];
+                Vector<WorkItem, 16> m_workQueue;
         };
 
         ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value)
             : JSCell(globalData->stringStructure.get())
         };
 
         ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value)
             : JSCell(globalData->stringStructure.get())
-            , m_stringLength(value.size())
+            , m_length(value.size())
             , m_value(value)
             , m_value(value)
-            , m_ropeLength(0)
+            , m_fiberCount(0)
         {
         {
+            ASSERT(!m_value.isNull());
             Heap::heap(this)->reportExtraMemoryCost(value.cost());
         }
 
         enum HasOtherOwnerType { HasOtherOwner };
         JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType)
             : JSCell(globalData->stringStructure.get())
             Heap::heap(this)->reportExtraMemoryCost(value.cost());
         }
 
         enum HasOtherOwnerType { HasOtherOwner };
         JSString(JSGlobalData* globalData, const UString& value, HasOtherOwnerType)
             : JSCell(globalData->stringStructure.get())
-            , m_stringLength(value.size())
+            , m_length(value.size())
             , m_value(value)
             , m_value(value)
-            , m_ropeLength(0)
+            , m_fiberCount(0)
         {
         {
+            ASSERT(!m_value.isNull());
         }
         }
-        JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType)
+        JSString(JSGlobalData* globalData, PassRefPtr<UStringImpl> value, HasOtherOwnerType)
             : JSCell(globalData->stringStructure.get())
             : JSCell(globalData->stringStructure.get())
-            , m_stringLength(value->size())
+            , m_length(value->length())
             , m_value(value)
             , m_value(value)
-            , m_ropeLength(0)
+            , m_fiberCount(0)
         {
         {
+            ASSERT(!m_value.isNull());
         }
         }
-        JSString(JSGlobalData* globalData, PassRefPtr<JSString::Rope> rope)
+        JSString(JSGlobalData* globalData, PassRefPtr<RopeImpl> rope)
             : JSCell(globalData->stringStructure.get())
             : JSCell(globalData->stringStructure.get())
-            , m_stringLength(rope->stringLength())
-            , m_ropeLength(1)
+            , m_length(rope->length())
+            , m_fiberCount(1)
         {
         {
-            m_fibers[0] = rope.releaseRef();
+            m_other.m_fibers[0] = rope.releaseRef();
         }
         // This constructor constructs a new string by concatenating s1 & s2.
         }
         // This constructor constructs a new string by concatenating s1 & s2.
-        // This should only be called with ropeLength <= 3.
-        JSString(JSGlobalData* globalData, unsigned ropeLength, JSString* s1, JSString* s2)
+        // This should only be called with fiberCount <= 3.
+        JSString(JSGlobalData* globalData, unsigned fiberCount, JSString* s1, JSString* s2)
             : JSCell(globalData->stringStructure.get())
             : JSCell(globalData->stringStructure.get())
-            , m_stringLength(s1->length() + s2->length())
-            , m_ropeLength(ropeLength)
+            , m_length(s1->length() + s2->length())
+            , m_fiberCount(fiberCount)
         {
         {
-            ASSERT(ropeLength <= s_maxInternalRopeLength);
+            ASSERT(fiberCount <= s_maxInternalRopeLength);
             unsigned index = 0;
             appendStringInConstruct(index, s1);
             appendStringInConstruct(index, s2);
             unsigned index = 0;
             appendStringInConstruct(index, s1);
             appendStringInConstruct(index, s2);
-            ASSERT(ropeLength == index);
+            ASSERT(fiberCount == index);
         }
         // This constructor constructs a new string by concatenating s1 & s2.
         }
         // This constructor constructs a new string by concatenating s1 & s2.
-        // This should only be called with ropeLength <= 3.
-        JSString(JSGlobalData* globalData, unsigned ropeLength, JSString* s1, const UString& u2)
+        // This should only be called with fiberCount <= 3.
+        JSString(JSGlobalData* globalData, unsigned fiberCount, JSString* s1, const UString& u2)
             : JSCell(globalData->stringStructure.get())
             : JSCell(globalData->stringStructure.get())
-            , m_stringLength(s1->length() + u2.size())
-            , m_ropeLength(ropeLength)
+            , m_length(s1->length() + u2.size())
+            , m_fiberCount(fiberCount)
         {
         {
-            ASSERT(ropeLength <= s_maxInternalRopeLength);
+            ASSERT(fiberCount <= s_maxInternalRopeLength);
             unsigned index = 0;
             appendStringInConstruct(index, s1);
             appendStringInConstruct(index, u2);
             unsigned index = 0;
             appendStringInConstruct(index, s1);
             appendStringInConstruct(index, u2);
-            ASSERT(ropeLength == index);
+            ASSERT(fiberCount == index);
         }
         // This constructor constructs a new string by concatenating s1 & s2.
         }
         // This constructor constructs a new string by concatenating s1 & s2.
-        // This should only be called with ropeLength <= 3.
-        JSString(JSGlobalData* globalData, unsigned ropeLength, const UString& u1, JSString* s2)
+        // This should only be called with fiberCount <= 3.
+        JSString(JSGlobalData* globalData, unsigned fiberCount, const UString& u1, JSString* s2)
             : JSCell(globalData->stringStructure.get())
             : JSCell(globalData->stringStructure.get())
-            , m_stringLength(u1.size() + s2->length())
-            , m_ropeLength(ropeLength)
+            , m_length(u1.size() + s2->length())
+            , m_fiberCount(fiberCount)
         {
         {
-            ASSERT(ropeLength <= s_maxInternalRopeLength);
+            ASSERT(fiberCount <= s_maxInternalRopeLength);
             unsigned index = 0;
             appendStringInConstruct(index, u1);
             appendStringInConstruct(index, s2);
             unsigned index = 0;
             appendStringInConstruct(index, u1);
             appendStringInConstruct(index, s2);
-            ASSERT(ropeLength == index);
+            ASSERT(fiberCount == index);
         }
         // This constructor constructs a new string by concatenating v1, v2 & v3.
         }
         // This constructor constructs a new string by concatenating v1, v2 & v3.
-        // This should only be called with ropeLength <= 3 ... which since every
-        // value must require a ropeLength of at least one implies that the length
+        // This should only be called with fiberCount <= 3 ... which since every
+        // value must require a fiberCount of at least one implies that the length
         // for each value must be exactly 1!
         JSString(ExecState* exec, JSValue v1, JSValue v2, JSValue v3)
             : JSCell(exec->globalData().stringStructure.get())
         // for each value must be exactly 1!
         JSString(ExecState* exec, JSValue v1, JSValue v2, JSValue v3)
             : JSCell(exec->globalData().stringStructure.get())
-            , m_stringLength(0)
-            , m_ropeLength(s_maxInternalRopeLength)
+            , m_length(0)
+            , m_fiberCount(s_maxInternalRopeLength)
         {
             unsigned index = 0;
             appendValueInConstructAndIncrementLength(exec, index, v1);
         {
             unsigned index = 0;
             appendValueInConstructAndIncrementLength(exec, index, v1);
@@ -251,28 +273,52 @@ namespace JSC {
             ASSERT(index == s_maxInternalRopeLength);
         }
 
             ASSERT(index == s_maxInternalRopeLength);
         }
 
+        // This constructor constructs a new string by concatenating u1 & u2.
+        JSString(JSGlobalData* globalData, const UString& u1, const UString& u2)
+            : JSCell(globalData->stringStructure.get())
+            , m_length(u1.size() + u2.size())
+            , m_fiberCount(2)
+        {
+            unsigned index = 0;
+            appendStringInConstruct(index, u1);
+            appendStringInConstruct(index, u2);
+            ASSERT(index <= s_maxInternalRopeLength);
+        }
+
+        // This constructor constructs a new string by concatenating u1, u2 & u3.
+        JSString(JSGlobalData* globalData, const UString& u1, const UString& u2, const UString& u3)
+            : JSCell(globalData->stringStructure.get())
+            , m_length(u1.size() + u2.size() + u3.size())
+            , m_fiberCount(s_maxInternalRopeLength)
+        {
+            unsigned index = 0;
+            appendStringInConstruct(index, u1);
+            appendStringInConstruct(index, u2);
+            appendStringInConstruct(index, u3);
+            ASSERT(index <= s_maxInternalRopeLength);
+        }
+
         JSString(JSGlobalData* globalData, const UString& value, JSStringFinalizerCallback finalizer, void* context)
             : JSCell(globalData->stringStructure.get())
         JSString(JSGlobalData* globalData, const UString& value, JSStringFinalizerCallback finalizer, void* context)
             : JSCell(globalData->stringStructure.get())
-            , m_stringLength(value.size())
+            , m_length(value.size())
             , m_value(value)
             , m_value(value)
-            , m_ropeLength(0)
+            , m_fiberCount(0)
         {
         {
+            ASSERT(!m_value.isNull());
             // nasty hack because we can't union non-POD types
             // nasty hack because we can't union non-POD types
-            m_fibers[0] = reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(finalizer));
-            m_fibers[1] = context;
+            m_other.m_finalizerCallback = finalizer;
+            m_other.m_finalizerContext = context;
             Heap::heap(this)->reportExtraMemoryCost(value.cost());
         }
 
         ~JSString()
         {
             ASSERT(vptr() == JSGlobalData::jsStringVPtr);
             Heap::heap(this)->reportExtraMemoryCost(value.cost());
         }
 
         ~JSString()
         {
             ASSERT(vptr() == JSGlobalData::jsStringVPtr);
-            for (unsigned i = 0; i < m_ropeLength; ++i)
-                m_fibers[i].deref();
+            for (unsigned i = 0; i < m_fiberCount; ++i)
+                RopeImpl::deref(m_other.m_fibers[i]);
 
 
-            if (!m_ropeLength && m_fibers[0].nonFiber()) {
-                JSStringFinalizerCallback finalizer = reinterpret_cast<JSStringFinalizerCallback>(m_fibers[0].nonFiber());
-                finalizer(this, m_fibers[1].nonFiber());
-            }
+            if (!m_fiberCount && m_other.m_finalizerCallback)
+                m_other.m_finalizerCallback(this, m_other.m_finalizerContext);
         }
 
         const UString& value(ExecState* exec) const
         }
 
         const UString& value(ExecState* exec) const
@@ -281,20 +327,23 @@ namespace JSC {
                 resolveRope(exec);
             return m_value;
         }
                 resolveRope(exec);
             return m_value;
         }
-        const UString tryGetValue() const
+        const UString& tryGetValue() const
         {
             if (isRope())
         {
             if (isRope())
-                UString();
+                resolveRope(0);
             return m_value;
         }
             return m_value;
         }
-        unsigned length() { return m_stringLength; }
+        unsigned length() { return m_length; }
 
         bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
         bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&);
 
 
         bool getStringPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
         bool getStringPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
         bool getStringPropertyDescriptor(ExecState*, const Identifier& propertyName, PropertyDescriptor&);
 
-        bool canGetIndex(unsigned i) { return i < m_stringLength; }
+        bool canGetIndex(unsigned i) { return i < m_length; }
         JSString* getIndex(ExecState*, unsigned);
         JSString* getIndex(ExecState*, unsigned);
+        JSString* getIndexSlowCase(ExecState*, unsigned);
+
+        JSValue replaceCharacter(ExecState*, UChar, const UString& replacement);
 
         static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); }
 
 
         static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); }
 
@@ -302,7 +351,7 @@ namespace JSC {
         enum VPtrStealingHackType { VPtrStealingHack };
         JSString(VPtrStealingHackType) 
             : JSCell(0)
         enum VPtrStealingHackType { VPtrStealingHack };
         JSString(VPtrStealingHackType) 
             : JSCell(0)
-            , m_ropeLength(0)
+            , m_fiberCount(0)
         {
         }
 
         {
         }
 
@@ -310,14 +359,19 @@ namespace JSC {
 
         void appendStringInConstruct(unsigned& index, const UString& string)
         {
 
         void appendStringInConstruct(unsigned& index, const UString& string)
         {
-            m_fibers[index++] = Rope::Fiber(string.rep()->ref());
+            UStringImpl* impl = string.rep();
+            impl->ref();
+            m_other.m_fibers[index++] = impl;
         }
 
         void appendStringInConstruct(unsigned& index, JSString* jsString)
         {
             if (jsString->isRope()) {
         }
 
         void appendStringInConstruct(unsigned& index, JSString* jsString)
         {
             if (jsString->isRope()) {
-                for (unsigned i = 0; i < jsString->m_ropeLength; ++i)
-                    m_fibers[index++] = jsString->m_fibers[i].ref();
+                for (unsigned i = 0; i < jsString->m_fiberCount; ++i) {
+                    RopeImpl::Fiber fiber = jsString->m_other.m_fibers[i];
+                    fiber->ref();
+                    m_other.m_fibers[index++] = fiber;
+                }
             } else
                 appendStringInConstruct(index, jsString->string());
         }
             } else
                 appendStringInConstruct(index, jsString->string());
         }
@@ -327,13 +381,15 @@ namespace JSC {
             if (v.isString()) {
                 ASSERT(asCell(v)->isString());
                 JSString* s = static_cast<JSString*>(asCell(v));
             if (v.isString()) {
                 ASSERT(asCell(v)->isString());
                 JSString* s = static_cast<JSString*>(asCell(v));
-                ASSERT(s->ropeLength() == 1);
+                ASSERT(s->size() == 1);
                 appendStringInConstruct(index, s);
                 appendStringInConstruct(index, s);
-                m_stringLength += s->length();
+                m_length += s->length();
             } else {
                 UString u(v.toString(exec));
             } else {
                 UString u(v.toString(exec));
-                m_fibers[index++] = Rope::Fiber(u.rep()->ref());
-                m_stringLength += u.size();
+                UStringImpl* impl = u.rep();
+                impl->ref();
+                m_other.m_fibers[index++] = impl;
+                m_length += u.size();
             }
         }
 
             }
         }
 
@@ -345,8 +401,6 @@ namespace JSC {
         virtual UString toString(ExecState*) const;
 
         virtual JSObject* toThisObject(ExecState*) const;
         virtual UString toString(ExecState*) const;
 
         virtual JSObject* toThisObject(ExecState*) const;
-        virtual UString toThisString(ExecState*) const;
-        virtual JSString* toThisJSString(ExecState*);
 
         // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
 
         // Actually getPropertySlot, not getOwnPropertySlot (see JSCell).
         virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
@@ -355,15 +409,25 @@ namespace JSC {
 
         static const unsigned s_maxInternalRopeLength = 3;
 
 
         static const unsigned s_maxInternalRopeLength = 3;
 
-        // A string is represented either by a UString or a Rope.
-        unsigned m_stringLength;
+        // A string is represented either by a UString or a RopeImpl.
+        unsigned m_length;
         mutable UString m_value;
         mutable UString m_value;
-        mutable unsigned m_ropeLength;
-        mutable Rope::Fiber m_fibers[s_maxInternalRopeLength];
+        mutable unsigned m_fiberCount;
+        // This structure exists to support a temporary workaround for a GC issue.
+        struct JSStringFinalizerStruct {
+            JSStringFinalizerStruct() : m_finalizerCallback(0) {}
+            union {
+                mutable RopeImpl::Fiber m_fibers[s_maxInternalRopeLength];
+                struct {
+                    JSStringFinalizerCallback m_finalizerCallback;
+                    void* m_finalizerContext;
+                };
+            };
+        } m_other;
 
 
-        bool isRope() const { return m_ropeLength; }
+        bool isRope() const { return m_fiberCount; }
         UString& string() { ASSERT(!isRope()); return m_value; }
         UString& string() { ASSERT(!isRope()); return m_value; }
-        unsigned ropeLength() { return m_ropeLength ? m_ropeLength : 1; }
+        unsigned size() { return m_fiberCount ? m_fiberCount : 1; }
 
         friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2);
         friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2);
 
         friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2);
         friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2);
@@ -403,13 +467,14 @@ namespace JSC {
         return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(&c, 1)));
     }
 
         return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(&c, 1)));
     }
 
-    inline JSString* jsSingleCharacterSubstring(JSGlobalData* globalData, const UString& s, unsigned offset)
+    inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset)
     {
     {
+        JSGlobalData* globalData = &exec->globalData();
         ASSERT(offset < static_cast<unsigned>(s.size()));
         UChar c = s.data()[offset];
         if (c <= 0xFF)
             return globalData->smallStrings.singleCharacterString(globalData, c);
         ASSERT(offset < static_cast<unsigned>(s.size()));
         UChar c = s.data()[offset];
         if (c <= 0xFF)
             return globalData->smallStrings.singleCharacterString(globalData, c);
-        return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, 1))));
+        return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UStringImpl::create(s.rep(), offset, 1))));
     }
 
     inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s)
     }
 
     inline JSString* jsNontrivialString(JSGlobalData* globalData, const char* s)
@@ -429,7 +494,10 @@ namespace JSC {
     inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
     {
         ASSERT(canGetIndex(i));
     inline JSString* JSString::getIndex(ExecState* exec, unsigned i)
     {
         ASSERT(canGetIndex(i));
-        return jsSingleCharacterSubstring(&exec->globalData(), value(exec), i);
+        if (isRope())
+            return getIndexSlowCase(exec, i);
+        ASSERT(i < m_value.size());
+        return jsSingleCharacterSubstring(exec, m_value, i);
     }
 
     inline JSString* jsString(JSGlobalData* globalData, const UString& s)
     }
 
     inline JSString* jsString(JSGlobalData* globalData, const UString& s)
@@ -464,7 +532,7 @@ namespace JSC {
             if (c <= 0xFF)
                 return globalData->smallStrings.singleCharacterString(globalData, c);
         }
             if (c <= 0xFF)
                 return globalData->smallStrings.singleCharacterString(globalData, c);
         }
-        return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UString::Rep::create(s.rep(), offset, length)), JSString::HasOtherOwner));
+        return fixupVPtr(globalData, new (globalData) JSString(globalData, UString(UStringImpl::create(s.rep(), offset, length)), JSString::HasOtherOwner));
     }
 
     inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s)
     }
 
     inline JSString* jsOwnedString(JSGlobalData* globalData, const UString& s)
@@ -483,7 +551,6 @@ namespace JSC {
     inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); }
     inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); }
     inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); }
     inline JSString* jsEmptyString(ExecState* exec) { return jsEmptyString(&exec->globalData()); }
     inline JSString* jsString(ExecState* exec, const UString& s) { return jsString(&exec->globalData(), s); }
     inline JSString* jsSingleCharacterString(ExecState* exec, UChar c) { return jsSingleCharacterString(&exec->globalData(), c); }
-    inline JSString* jsSingleCharacterSubstring(ExecState* exec, const UString& s, unsigned offset) { return jsSingleCharacterSubstring(&exec->globalData(), s, offset); }
     inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); }
     inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); }
     inline JSString* jsNontrivialString(ExecState* exec, const char* s) { return jsNontrivialString(&exec->globalData(), s); }
     inline JSString* jsSubstring(ExecState* exec, const UString& s, unsigned offset, unsigned length) { return jsSubstring(&exec->globalData(), s, offset, length); }
     inline JSString* jsNontrivialString(ExecState* exec, const UString& s) { return jsNontrivialString(&exec->globalData(), s); }
     inline JSString* jsNontrivialString(ExecState* exec, const char* s) { return jsNontrivialString(&exec->globalData(), s); }
@@ -492,14 +559,14 @@ namespace JSC {
     ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
     {
         if (propertyName == exec->propertyNames().length) {
     ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
     {
         if (propertyName == exec->propertyNames().length) {
-            slot.setValue(jsNumber(exec, m_stringLength));
+            slot.setValue(jsNumber(exec, m_length));
             return true;
         }
 
         bool isStrictUInt32;
         unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
             return true;
         }
 
         bool isStrictUInt32;
         unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
-        if (isStrictUInt32 && i < m_stringLength) {
-            slot.setValue(jsSingleCharacterSubstring(exec, value(exec), i));
+        if (isStrictUInt32 && i < m_length) {
+            slot.setValue(getIndex(exec, i));
             return true;
         }
 
             return true;
         }
 
@@ -508,8 +575,8 @@ namespace JSC {
         
     ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
     {
         
     ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
     {
-        if (propertyName < m_stringLength) {
-            slot.setValue(jsSingleCharacterSubstring(exec, value(exec), propertyName));
+        if (propertyName < m_length) {
+            slot.setValue(getIndex(exec, propertyName));
             return true;
         }
 
             return true;
         }
 
@@ -520,11 +587,6 @@ namespace JSC {
 
     // --- JSValue inlines ----------------------------
 
 
     // --- JSValue inlines ----------------------------
 
-    inline JSString* JSValue::toThisJSString(ExecState* exec)
-    {
-        return isCell() ? asCell()->toThisJSString(exec) : jsString(exec, toString(exec));
-    }
-
     inline UString JSValue::toString(ExecState* exec) const
     {
         if (isString())
     inline UString JSValue::toString(ExecState* exec) const
     {
         if (isString())
diff --git a/runtime/JSStringBuilder.h b/runtime/JSStringBuilder.h
new file mode 100644 (file)
index 0000000..8f208a1
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * 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 JSStringBuilder_h
+#define JSStringBuilder_h
+
+#include "ExceptionHelpers.h"
+#include "JSString.h"
+#include "Vector.h"
+
+namespace JSC {
+
+class JSStringBuilder {
+public:
+    JSStringBuilder()
+        : m_okay(true)
+    {
+    }
+
+    void append(const UChar u)
+    {
+        m_okay &= buffer.tryAppend(&u, 1);
+    }
+
+    void append(const char* str)
+    {
+        append(str, strlen(str));
+    }
+
+    void append(const char* str, size_t len)
+    {
+        m_okay &= buffer.tryReserveCapacity(buffer.size() + len);
+        for (size_t i = 0; i < len; i++) {
+            UChar u = static_cast<unsigned char>(str[i]);
+            m_okay &= buffer.tryAppend(&u, 1);
+        }
+    }
+
+    void append(const UChar* str, size_t len)
+    {
+        m_okay &= buffer.tryAppend(str, len);
+    }
+
+    void append(const UString& str)
+    {
+        m_okay &= buffer.tryAppend(str.data(), str.size());
+    }
+
+    JSValue build(ExecState* exec)
+    {
+        if (!m_okay)
+            return throwOutOfMemoryError(exec);
+        buffer.shrinkToFit();
+        if (!buffer.data())
+            return throwOutOfMemoryError(exec);
+        return jsString(exec, UString::adopt(buffer));
+    }
+
+protected:
+    Vector<UChar, 64> buffer;
+    bool m_okay;
+};
+
+template<typename StringType1, typename StringType2>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2)
+{
+    PassRefPtr<UStringImpl> result = tryMakeString(string1, string2);
+    if (!result)
+        return throwOutOfMemoryError(exec);
+    return jsNontrivialString(exec, result);
+}
+
+template<typename StringType1, typename StringType2, typename StringType3>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3)
+{
+    PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3);
+    if (!result)
+        return throwOutOfMemoryError(exec);
+    return jsNontrivialString(exec, result);
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+{
+    PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4);
+    if (!result)
+        return throwOutOfMemoryError(exec);
+    return jsNontrivialString(exec, result);
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+{
+    PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4, string5);
+    if (!result)
+        return throwOutOfMemoryError(exec);
+    return jsNontrivialString(exec, result);
+}
+
+template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
+inline JSValue jsMakeNontrivialString(ExecState* exec, StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+{
+    PassRefPtr<UStringImpl> result = tryMakeString(string1, string2, string3, string4, string5, string6);
+    if (!result)
+        return throwOutOfMemoryError(exec);
+    return jsNontrivialString(exec, result);
+}
+
+}
+
+#endif
index 7c8960071d7521ab77721ef679d106683c072b7e..e225bc72ce78a6958f004329e930bc051ba88e8b 100644 (file)
@@ -50,6 +50,8 @@ namespace JSC {
         TypeInfo(JSType type, unsigned flags = 0)
             : m_type(type)
         {
         TypeInfo(JSType type, unsigned flags = 0)
             : m_type(type)
         {
+            ASSERT(flags <= 0xFF);
+            ASSERT(type <= 0xFF);
             // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
             if ((flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
                 m_flags = flags | ImplementsDefaultHasInstance;
             // ImplementsDefaultHasInstance means (ImplementsHasInstance & !OverridesHasInstance)
             if ((flags & (ImplementsHasInstance | OverridesHasInstance)) == ImplementsHasInstance)
                 m_flags = flags | ImplementsDefaultHasInstance;
@@ -57,7 +59,7 @@ namespace JSC {
                 m_flags = flags;
         }
 
                 m_flags = flags;
         }
 
-        JSType type() const { return m_type; }
+        JSType type() const { return (JSType)m_type; }
 
         bool masqueradesAsUndefined() const { return m_flags & MasqueradesAsUndefined; }
         bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; }
 
         bool masqueradesAsUndefined() const { return m_flags & MasqueradesAsUndefined; }
         bool implementsHasInstance() const { return m_flags & ImplementsHasInstance; }
@@ -69,8 +71,8 @@ namespace JSC {
         unsigned flags() const { return m_flags; }
 
     private:
         unsigned flags() const { return m_flags; }
 
     private:
-        JSType m_type;
-        unsigned m_flags;
+        unsigned char m_type;
+        unsigned char m_flags;
     };
 
 }
     };
 
 }
index 699c1cd7ccf79dbdea66ec293ec2b8521d7bb10c..502312caeaac6b1415c9f7c7a17010fe89102bd2 100644 (file)
@@ -174,7 +174,11 @@ uint32_t toUInt32SlowCase(double d, bool& ok)
 
 NEVER_INLINE double nonInlineNaN()
 {
 
 NEVER_INLINE double nonInlineNaN()
 {
+#if OS(SYMBIAN)
+    return nanval();
+#else
     return std::numeric_limits<double>::quiet_NaN();
     return std::numeric_limits<double>::quiet_NaN();
+#endif
 }
 
 } // namespace JSC
 }
 
 } // namespace JSC
index 6da921f307cba69ff9babb7b862c461a3e516034..52f89948a3b957c69a2f27a1e82a5bc6956e87b3 100644 (file)
@@ -66,6 +66,8 @@ namespace JSC {
         friend class JIT;
         friend class JITStubs;
         friend class JITStubCall;
         friend class JIT;
         friend class JITStubs;
         friend class JITStubCall;
+        friend class JSInterfaceJIT;
+        friend class SpecializedThunkJIT;
 
     public:
         static EncodedJSValue encode(JSValue value);
 
     public:
         static EncodedJSValue encode(JSValue value);
@@ -183,12 +185,13 @@ namespace JSC {
         JSValue get(ExecState*, unsigned propertyName) const;
         JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
         void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         JSValue get(ExecState*, unsigned propertyName) const;
         JSValue get(ExecState*, unsigned propertyName, PropertySlot&) const;
         void put(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+        void putDirect(ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
         void put(ExecState*, unsigned propertyName, JSValue);
 
         bool needsThisConversion() const;
         JSObject* toThisObject(ExecState*) const;
         UString toThisString(ExecState*) const;
         void put(ExecState*, unsigned propertyName, JSValue);
 
         bool needsThisConversion() const;
         JSObject* toThisObject(ExecState*) const;
         UString toThisString(ExecState*) const;
-        JSString* toThisJSString(ExecState*);
+        JSString* toThisJSString(ExecState*) const;
 
         static bool equal(ExecState* exec, JSValue v1, JSValue v2);
         static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
 
         static bool equal(ExecState* exec, JSValue v1, JSValue v2);
         static bool equalSlowCase(ExecState* exec, JSValue v1, JSValue v2);
@@ -214,6 +217,10 @@ namespace JSC {
         JSObject* toObjectSlowCase(ExecState*) const;
         JSObject* toThisObjectSlowCase(ExecState*) const;
 
         JSObject* toObjectSlowCase(ExecState*) const;
         JSObject* toThisObjectSlowCase(ExecState*) const;
 
+        JSObject* synthesizePrototype(ExecState*) const;
+        JSObject* synthesizeObject(ExecState*) const;
+
+#if USE(JSVALUE32_64)
         enum { Int32Tag =        0xffffffff };
         enum { CellTag =         0xfffffffe };
         enum { TrueTag =         0xfffffffd };
         enum { Int32Tag =        0xffffffff };
         enum { CellTag =         0xfffffffe };
         enum { TrueTag =         0xfffffffd };
@@ -222,16 +229,12 @@ namespace JSC {
         enum { UndefinedTag =    0xfffffffa };
         enum { EmptyValueTag =   0xfffffff9 };
         enum { DeletedValueTag = 0xfffffff8 };
         enum { UndefinedTag =    0xfffffffa };
         enum { EmptyValueTag =   0xfffffff9 };
         enum { DeletedValueTag = 0xfffffff8 };
-
+        
         enum { LowestTag =  DeletedValueTag };
         enum { LowestTag =  DeletedValueTag };
-
+        
         uint32_t tag() const;
         int32_t payload() const;
 
         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;
         union {
             EncodedJSValue asEncodedJSValue;
             double asDouble;
index 6c679ce0720c58597f29d6bd10bf0ba9f9be0202..f2efcdf3989affb0b2ef4b6765ce5f8c6a0939ad 100644 (file)
@@ -52,7 +52,7 @@ namespace JSC {
         virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         
         virtual bool isVariableObject() const;
         virtual void getOwnPropertyNames(ExecState*, PropertyNameArray&, EnumerationMode mode = ExcludeDontEnumProperties);
         
         virtual bool isVariableObject() const;
-        virtual bool isDynamicScope() const = 0;
+        virtual bool isDynamicScope(bool& requiresDynamicChecks) const = 0;
 
         Register& registerAt(int index) const { return d->registers[index]; }
 
 
         Register& registerAt(int index) const { return d->registers[index]; }
 
index 8b33ea61bf1d6fce263e21ba13b86c5dbafc3438..711f6732bcceaeb81c0e07770c234d2720150f54 100644 (file)
@@ -60,8 +60,6 @@ public:
     virtual bool deleteProperty(ExecState*, const Identifier&) { ASSERT_NOT_REACHED(); return false; }
     virtual bool deleteProperty(ExecState*, unsigned) { ASSERT_NOT_REACHED(); return false; }
     virtual JSObject* toThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; }
     virtual bool deleteProperty(ExecState*, const Identifier&) { ASSERT_NOT_REACHED(); return false; }
     virtual bool deleteProperty(ExecState*, unsigned) { ASSERT_NOT_REACHED(); return false; }
     virtual JSObject* toThisObject(ExecState*) const { ASSERT_NOT_REACHED(); return 0; }
-    virtual UString toThisString(ExecState*) const { ASSERT_NOT_REACHED(); return ""; }
-    virtual JSString* toThisJSString(ExecState*) { ASSERT_NOT_REACHED(); return 0; }
     virtual JSValue getJSNumber() { ASSERT_NOT_REACHED(); return jsNull(); }
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
     virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
     virtual JSValue getJSNumber() { ASSERT_NOT_REACHED(); return jsNull(); }
     virtual bool getOwnPropertySlot(ExecState*, const Identifier&, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
     virtual bool getOwnPropertySlot(ExecState*, unsigned, PropertySlot&) { ASSERT_NOT_REACHED(); return false; }
index aa1e5ed9f63e63a76731b9cc068905470d54179e..cc33bae187be78c14c6fb3a515cdc2577ecf4beb 100644 (file)
@@ -200,7 +200,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
     if (m_ptr >= m_end || *m_ptr != '"')
         return TokError;
 
     if (m_ptr >= m_end || *m_ptr != '"')
         return TokError;
 
-    token.stringToken = builder.release();
+    token.stringToken = builder.build();
     token.type = TokString;
     token.end = ++m_ptr;
     return TokString;
     token.type = TokString;
     token.end = ++m_ptr;
     return TokString;
index 4e9e08602914721cfdd2e05e6dd33c6af4e06be5..cc1981257fed01b34fd80ca4df527e090ec9e086 100644 (file)
@@ -46,7 +46,11 @@ void HashTable::createTable(JSGlobalData* globalData) const
             entry = entry->next();
         }
 
             entry = entry->next();
         }
 
-        entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2);
+        entry->initialize(identifier, values[i].attributes, values[i].value1, values[i].value2
+#if ENABLE(JIT)
+                          , values[i].generator
+#endif
+                          );
     }
     table = entries;
 }
     }
     table = entries;
 }
@@ -70,7 +74,13 @@ void setUpStaticFunctionSlot(ExecState* exec, const HashEntry* entry, JSObject*
     JSValue* location = thisObj->getDirectLocation(propertyName);
 
     if (!location) {
     JSValue* location = thisObj->getDirectLocation(propertyName);
 
     if (!location) {
-        InternalFunction* function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function());
+        InternalFunction* function;
+#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
+        if (entry->generator())
+            function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, exec->globalData().getThunk(entry->generator()), entry->function());
+        else
+#endif
+            function = new (exec) NativeFunctionWrapper(exec, exec->lexicalGlobalObject()->prototypeFunctionStructure(), entry->functionLength(), propertyName, entry->function());
 
         thisObj->putDirectFunction(propertyName, function, entry->attributes());
         location = thisObj->getDirectLocation(propertyName);
 
         thisObj->putDirectFunction(propertyName, function, entry->attributes());
         location = thisObj->getDirectLocation(propertyName);
index e673c09750e68c26a7028e7b33a94e388fe6a4f6..dd36400622424b51826e452718006ff41c38e6fc 100644 (file)
 #endif
 
 namespace JSC {
 #endif
 
 namespace JSC {
-
     // Hash table generated by the create_hash_table script.
     struct HashTableValue {
         const char* key; // property name
         unsigned char attributes; // JSObject attributes
         intptr_t value1;
         intptr_t value2;
     // Hash table generated by the create_hash_table script.
     struct HashTableValue {
         const char* key; // property name
         unsigned char attributes; // JSObject attributes
         intptr_t value1;
         intptr_t value2;
+#if ENABLE(JIT)
+        ThunkGenerator generator;
+#endif
     };
 
     // FIXME: There is no reason this get function can't be simpler.
     };
 
     // FIXME: There is no reason this get function can't be simpler.
@@ -53,12 +55,19 @@ namespace JSC {
 
     class HashEntry : public FastAllocBase {
     public:
 
     class HashEntry : public FastAllocBase {
     public:
-        void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2)
+        void initialize(UString::Rep* key, unsigned char attributes, intptr_t v1, intptr_t v2
+#if ENABLE(JIT)
+                        , ThunkGenerator generator = 0
+#endif
+                        )
         {
             m_key = key;
             m_attributes = attributes;
             m_u.store.value1 = v1;
             m_u.store.value2 = v2;
         {
             m_key = key;
             m_attributes = attributes;
             m_u.store.value1 = v1;
             m_u.store.value2 = v2;
+#if ENABLE(JIT)
+            m_u.function.generator = generator;
+#endif
             m_next = 0;
         }
 
             m_next = 0;
         }
 
@@ -67,6 +76,9 @@ namespace JSC {
 
         unsigned char attributes() const { return m_attributes; }
 
 
         unsigned char attributes() const { return m_attributes; }
 
+#if ENABLE(JIT)
+        ThunkGenerator generator() const { ASSERT(m_attributes & Function); return m_u.function.generator; }
+#endif
         NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; }
         unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_u.function.length); }
 
         NativeFunction function() const { ASSERT(m_attributes & Function); return m_u.function.functionValue; }
         unsigned char functionLength() const { ASSERT(m_attributes & Function); return static_cast<unsigned char>(m_u.function.length); }
 
@@ -90,6 +102,9 @@ namespace JSC {
             struct {
                 NativeFunction functionValue;
                 intptr_t length; // number of arguments for function
             struct {
                 NativeFunction functionValue;
                 intptr_t length; // number of arguments for function
+#if ENABLE(JIT)
+                ThunkGenerator generator;
+#endif
             } function;
             struct {
                 GetFunction get;
             } function;
             struct {
                 GetFunction get;
@@ -181,7 +196,7 @@ namespace JSC {
         if (entry->attributes() & Function)
             setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
         else
         if (entry->attributes() & Function)
             setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
         else
-            slot.setCustom(thisObj, entry->propertyGetter());
+            slot.setCacheableCustom(thisObj, entry->propertyGetter());
 
         return true;
     }
 
         return true;
     }
@@ -258,7 +273,7 @@ namespace JSC {
 
         ASSERT(!(entry->attributes() & Function));
 
 
         ASSERT(!(entry->attributes() & Function));
 
-        slot.setCustom(thisObj, entry->propertyGetter());
+        slot.setCacheableCustom(thisObj, entry->propertyGetter());
         return true;
     }
 
         return true;
     }
 
index 98ff3ba8b3cb7f82f836ed0f7a1509aa773e87cb..78e14e3c42b6e93c4149fe167312bf7409f855e2 100644 (file)
@@ -21,6 +21,7 @@
 #include "config.h"
 #include "MathObject.h"
 
 #include "config.h"
 #include "MathObject.h"
 
+#include "Lookup.h"
 #include "ObjectPrototype.h"
 #include "Operations.h"
 #include <time.h>
 #include "ObjectPrototype.h"
 #include "Operations.h"
 #include <time.h>
@@ -210,20 +211,19 @@ JSValue JSC_HOST_CALL mathProtoFuncPow(ExecState* exec, JSObject*, JSValue, cons
 
 JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&)
 {
 
 JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, const ArgList&)
 {
-    return jsDoubleNumber(exec, exec->globalData().weakRandom.get());
+    return jsDoubleNumber(exec, exec->lexicalGlobalObject()->weakRandomNumber());
 }
 
 JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     double arg = args.at(0).toNumber(exec);
 }
 
 JSValue JSC_HOST_CALL mathProtoFuncRound(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
     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));
+    double integer = ceil(arg);
+    return jsNumber(exec, integer - (integer - arg > 0.5));
 }
 
 JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
 }
 
 JSValue JSC_HOST_CALL mathProtoFuncSin(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 {
-    return jsDoubleNumber(exec, sin(args.at(0).toNumber(exec)));
+    return exec->globalData().cachedSin(exec, args.at(0).toNumber(exec));
 }
 
 JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
 }
 
 JSValue JSC_HOST_CALL mathProtoFuncSqrt(ExecState* exec, JSObject*, JSValue, const ArgList& args)
index 403fc7ecca463e62c6b18491868bae817007d54a..36b4fd1d257489ccb10130acb2ad47278a9e3e0a 100644 (file)
@@ -32,14 +32,17 @@ ASSERT_CLASS_FITS_IN_CELL(NativeErrorConstructor);
 
 const ClassInfo NativeErrorConstructor::info = { "Function", &InternalFunction::info, 0, 0 };
 
 
 const ClassInfo NativeErrorConstructor::info = { "Function", &InternalFunction::info, 0, 0 };
 
-NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, NativeErrorPrototype* nativeErrorPrototype)
-    : InternalFunction(&exec->globalData(), structure, Identifier(exec, nativeErrorPrototype->getDirect(exec->propertyNames().name).getString(exec)))
-    , m_errorStructure(ErrorInstance::createStructure(nativeErrorPrototype))
+NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<Structure> prototypeStructure, const UString& nameAndMessage)
+    : InternalFunction(&exec->globalData(), structure, Identifier(exec, nameAndMessage))
 {
 {
+    NativeErrorPrototype* prototype = new (exec) NativeErrorPrototype(exec, prototypeStructure, nameAndMessage, this);
+
     putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
     putDirect(exec->propertyNames().length, jsNumber(exec, 1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
-    putDirect(exec->propertyNames().prototype, nativeErrorPrototype, DontDelete | ReadOnly | DontEnum);
+    putDirect(exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum);
+    m_errorStructure = ErrorInstance::createStructure(prototype);
 }
 
 }
 
+
 ErrorInstance* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
 {
     ErrorInstance* object = new (exec) ErrorInstance(m_errorStructure);
 ErrorInstance* NativeErrorConstructor::construct(ExecState* exec, const ArgList& args)
 {
     ErrorInstance* object = new (exec) ErrorInstance(m_errorStructure);
index 152dbac2f5a72647ab5e9893587154aa0e4961b8..891f9226b128421e58efb55518700659f0274e32 100644 (file)
@@ -31,7 +31,7 @@ namespace JSC {
 
     class NativeErrorConstructor : public InternalFunction {
     public:
 
     class NativeErrorConstructor : public InternalFunction {
     public:
-        NativeErrorConstructor(ExecState*, NonNullPassRefPtr<Structure>, NativeErrorPrototype*);
+        NativeErrorConstructor(ExecState*, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<Structure> prototypeStructure, const UString&);
 
         static const ClassInfo info;
 
 
         static const ClassInfo info;
 
index aa46a6a4292f4e965b4d99abaad7ad19b82d3790..43ae6664d939e1e4962c9e8ab92a1146ee1632b4 100644 (file)
 
 #include "ErrorPrototype.h"
 #include "JSString.h"
 
 #include "ErrorPrototype.h"
 #include "JSString.h"
+#include "NativeErrorConstructor.h"
 #include "UString.h"
 
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
 
 #include "UString.h"
 
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
 
-NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& name, const UString& message)
+NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& nameAndMessage, NativeErrorConstructor* constructor)
     : JSObject(structure)
 {
     : JSObject(structure)
 {
-    putDirect(exec->propertyNames().name, jsString(exec, name), 0);
-    putDirect(exec->propertyNames().message, jsString(exec, message), 0);
+    putDirect(exec->propertyNames().name, jsString(exec, nameAndMessage), 0);
+    putDirect(exec->propertyNames().message, jsString(exec, nameAndMessage), 0);
+    putDirect(exec->propertyNames().constructor, constructor, DontEnum);
 }
 
 } // namespace JSC
 }
 
 } // namespace JSC
index 0c65a9c3e45b935227b5b6a20a949ae40401a55a..19468f7444817044155e37eb07f42b0fac2d8c0c 100644 (file)
 #include "JSObject.h"
 
 namespace JSC {
 #include "JSObject.h"
 
 namespace JSC {
+    class NativeErrorConstructor;
 
     class NativeErrorPrototype : public JSObject {
     public:
 
     class NativeErrorPrototype : public JSObject {
     public:
-        NativeErrorPrototype(ExecState*, NonNullPassRefPtr<Structure>, const UString& name, const UString& message);
+        NativeErrorPrototype(ExecState*, NonNullPassRefPtr<Structure>, const UString&, NativeErrorConstructor*);
     };
 
 } // namespace JSC
     };
 
 } // namespace JSC
index cc6c51d4ea59fae4a14122d534430438236d1c09..0b7e8216e857c5bafa3b8b48fc2bb1bd81545abf 100644 (file)
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "NumberConstructor.h"
 
 #include "config.h"
 #include "NumberConstructor.h"
 
+#include "Lookup.h"
 #include "NumberObject.h"
 #include "NumberPrototype.h"
 
 #include "NumberObject.h"
 #include "NumberPrototype.h"
 
@@ -29,11 +30,11 @@ namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(NumberConstructor);
 
 
 ASSERT_CLASS_FITS_IN_CELL(NumberConstructor);
 
-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&);
+static JSValue numberConstructorNaNValue(ExecState*, JSValue, const Identifier&);
+static JSValue numberConstructorNegInfinity(ExecState*, JSValue, const Identifier&);
+static JSValue numberConstructorPosInfinity(ExecState*, JSValue, const Identifier&);
+static JSValue numberConstructorMaxValue(ExecState*, JSValue, const Identifier&);
+static JSValue numberConstructorMinValue(ExecState*, JSValue, const Identifier&);
 
 } // namespace JSC
 
 
 } // namespace JSC
 
@@ -73,27 +74,27 @@ bool NumberConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifi
     return getStaticValueDescriptor<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, descriptor);
 }
 
     return getStaticValueDescriptor<NumberConstructor, InternalFunction>(exec, ExecState::numberTable(exec), this, propertyName, descriptor);
 }
 
-static JSValue numberConstructorNaNValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorNaNValue(ExecState* exec, JSValue, const Identifier&)
 {
     return jsNaN(exec);
 }
 
 {
     return jsNaN(exec);
 }
 
-static JSValue numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorNegInfinity(ExecState* exec, JSValue, const Identifier&)
 {
     return jsNumber(exec, -Inf);
 }
 
 {
     return jsNumber(exec, -Inf);
 }
 
-static JSValue numberConstructorPosInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorPosInfinity(ExecState* exec, JSValue, const Identifier&)
 {
     return jsNumber(exec, Inf);
 }
 
 {
     return jsNumber(exec, Inf);
 }
 
-static JSValue numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorMaxValue(ExecState* exec, JSValue, const Identifier&)
 {
     return jsNumber(exec, 1.7976931348623157E+308);
 }
 
 {
     return jsNumber(exec, 1.7976931348623157E+308);
 }
 
-static JSValue numberConstructorMinValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorMinValue(ExecState* exec, JSValue, const Identifier&)
 {
     return jsNumber(exec, 5E-324);
 }
 {
     return jsNumber(exec, 5E-324);
 }
index 3ecc78628a5bd9908cf67767a1443ff009d1e356..16ceb5cd5525fee84a30e383dad0771d6b680cbb 100644 (file)
@@ -25,6 +25,7 @@
 #include "Error.h"
 #include "JSFunction.h"
 #include "JSString.h"
 #include "Error.h"
 #include "JSFunction.h"
 #include "JSString.h"
+#include "JSStringBuilder.h"
 #include "Operations.h"
 #include "PrototypeFunction.h"
 #include "StringBuilder.h"
 #include "Operations.h"
 #include "PrototypeFunction.h"
 #include "StringBuilder.h"
@@ -95,7 +96,7 @@ static UString integerPartNoExp(double d)
         builder.append((const char*)(buf.data()));
     }
 
         builder.append((const char*)(buf.data()));
     }
 
-    return builder.release();
+    return builder.build();
 }
 
 static UString charSequence(char c, int count)
 }
 
 static UString charSequence(char c, int count)
@@ -143,15 +144,34 @@ JSValue JSC_HOST_CALL numberProtoFuncToString(ExecState* exec, JSObject*, JSValu
     if (!v)
         return throwError(exec, TypeError);
 
     if (!v)
         return throwError(exec, TypeError);
 
-    double radixAsDouble = args.at(0).toInteger(exec); // nan -> 0
-    if (radixAsDouble == 10 || args.at(0).isUndefined())
+    JSValue radixValue = args.at(0);
+    int radix;
+    if (radixValue.isInt32())
+        radix = radixValue.asInt32();
+    else if (radixValue.isUndefined())
+        radix = 10;
+    else
+        radix = static_cast<int>(radixValue.toInteger(exec)); // nan -> 0
+
+    if (radix == 10)
         return jsString(exec, v.toString(exec));
 
         return jsString(exec, v.toString(exec));
 
-    if (radixAsDouble < 2 || radixAsDouble > 36)
+    static const char* const digits = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+    // Fast path for number to character conversion.
+    if (radix == 36) {
+        if (v.isInt32()) {
+            int x = v.asInt32();
+            if (static_cast<unsigned>(x) < 36) { // Exclude negatives
+                JSGlobalData* globalData = &exec->globalData();
+                return globalData->smallStrings.singleCharacterString(globalData, digits[x]);
+            }
+        }
+    }
+
+    if (radix < 2 || radix > 36)
         return throwError(exec, RangeError, "toString() radix argument must be between 2 and 36");
 
         return throwError(exec, RangeError, "toString() radix argument must be between 2 and 36");
 
-    int radix = static_cast<int>(radixAsDouble);
-    const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
     // INT_MAX results in 1024 characters left of the dot with radix 2
     // give the same space on the right side. safety checks are in place
     // unless someone finds a precise rule.
     // INT_MAX results in 1024 characters left of the dot with radix 2
     // give the same space on the right side. safety checks are in place
     // unless someone finds a precise rule.
@@ -263,13 +283,13 @@ JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue
         for (int i = 0; i < f + 1 - k; i++)
             z.append('0');
         z.append(m);
         for (int i = 0; i < f + 1 - k; i++)
             z.append('0');
         z.append(m);
-        m = z.release();
+        m = z.build();
         k = f + 1;
         k = f + 1;
-        ASSERT(k == m.size());
+        ASSERT(k == static_cast<int>(m.size()));
     }
     int kMinusf = k - f;
 
     }
     int kMinusf = k - f;
 
-    if (kMinusf < m.size())
+    if (kMinusf < static_cast<int>(m.size()))
         return jsString(exec, makeString(s, m.substr(0, kMinusf), ".", m.substr(kMinusf)));
     return jsString(exec, makeString(s, m.substr(0, kMinusf)));
 }
         return jsString(exec, makeString(s, m.substr(0, kMinusf), ".", m.substr(kMinusf)));
     return jsString(exec, makeString(s, m.substr(0, kMinusf)));
 }
@@ -433,8 +453,8 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
             if (m.size() > 1)
                 m = makeString(m.substr(0, 1), ".", m.substr(1));
             if (e >= 0)
             if (m.size() > 1)
                 m = makeString(m.substr(0, 1), ".", m.substr(1));
             if (e >= 0)
-                return jsNontrivialString(exec, makeString(s, m, "e+", UString::from(e)));
-            return jsNontrivialString(exec, makeString(s, m, "e-", UString::from(-e)));
+                return jsMakeNontrivialString(exec, s, m, "e+", UString::from(e));
+            return jsMakeNontrivialString(exec, s, m, "e-", UString::from(-e));
         }
     } else {
         m = charSequence('0', precision);
         }
     } else {
         m = charSequence('0', precision);
@@ -444,11 +464,11 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
     if (e == precision - 1)
         return jsString(exec, makeString(s, m));
     if (e >= 0) {
     if (e == precision - 1)
         return jsString(exec, makeString(s, m));
     if (e >= 0) {
-        if (e + 1 < m.size())
+        if (e + 1 < static_cast<int>(m.size()))
             return jsString(exec, makeString(s, m.substr(0, e + 1), ".", m.substr(e + 1)));
         return jsString(exec, makeString(s, m));
     }
             return jsString(exec, makeString(s, m.substr(0, e + 1), ".", m.substr(e + 1)));
         return jsString(exec, makeString(s, m));
     }
-    return jsNontrivialString(exec, makeString(s, "0.", charSequence('0', -(e + 1)), m));
+    return jsMakeNontrivialString(exec, s, "0.", charSequence('0', -(e + 1)), m);
 }
 
 } // namespace JSC
 }
 
 } // namespace JSC
index c0696a479a2786991b1591e5e8dad35c62a03667..89235af7766eb40b12f46913460f8988b039d8c3 100644 (file)
@@ -45,6 +45,8 @@ namespace JSC {
 
         UString add(int i)
         {
 
         UString add(int i)
         {
+            if (static_cast<unsigned>(i) < cacheSize)
+                return lookupSmallString(static_cast<unsigned>(i));
             CacheEntry<int>& entry = lookup(i);
             if (i == entry.key && !entry.value.isNull())
                 return entry.value;
             CacheEntry<int>& entry = lookup(i);
             if (i == entry.key && !entry.value.isNull())
                 return entry.value;
@@ -53,6 +55,17 @@ namespace JSC {
             return entry.value;
         }
 
             return entry.value;
         }
 
+        UString add(unsigned i)
+        {
+            if (i < cacheSize)
+                return lookupSmallString(static_cast<unsigned>(i));
+            CacheEntry<unsigned>& entry = lookup(i);
+            if (i == entry.key && !entry.value.isNull())
+                return entry.value;
+            entry.key = i;
+            entry.value = UString::from(i);
+            return entry.value;
+        }
     private:
         static const size_t cacheSize = 64;
 
     private:
         static const size_t cacheSize = 64;
 
@@ -64,9 +77,19 @@ namespace JSC {
 
         CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
         CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; }
 
         CacheEntry<double>& lookup(double d) { return doubleCache[WTF::FloatHash<double>::hash(d) & (cacheSize - 1)]; }
         CacheEntry<int>& lookup(int i) { return intCache[WTF::IntHash<int>::hash(i) & (cacheSize - 1)]; }
+        CacheEntry<unsigned>& lookup(unsigned i) { return unsignedCache[WTF::IntHash<unsigned>::hash(i) & (cacheSize - 1)]; }
+        const UString& lookupSmallString(unsigned i)
+        {
+            ASSERT(i < cacheSize);
+            if (smallIntCache[i].isNull())
+                smallIntCache[i] = UString::from(i);
+            return smallIntCache[i];
+        }
 
         CacheEntry<double> doubleCache[cacheSize];
         CacheEntry<int> intCache[cacheSize];
 
         CacheEntry<double> doubleCache[cacheSize];
         CacheEntry<int> intCache[cacheSize];
+        CacheEntry<unsigned> unsignedCache[cacheSize];
+        UString smallIntCache[cacheSize];
     };
 
 } // namespace JSC
     };
 
 } // namespace JSC
index 3065c6d068571a4ab6d74a13fb7a8ea5c2948a2b..c32a00734acc82800d4cdb6141dc16ba03324ce5 100644 (file)
@@ -24,6 +24,7 @@
 #include "Error.h"
 #include "JSFunction.h"
 #include "JSString.h"
 #include "Error.h"
 #include "JSFunction.h"
 #include "JSString.h"
+#include "JSStringBuilder.h"
 #include "PrototypeFunction.h"
 
 namespace JSC {
 #include "PrototypeFunction.h"
 
 namespace JSC {
@@ -148,7 +149,7 @@ JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*,
 
 JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
 
 JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
-    return jsNontrivialString(exec, makeString("[object ", thisValue.toThisObject(exec)->className(), "]"));
+    return jsMakeNontrivialString(exec, "[object ", thisValue.toThisObject(exec)->className(), "]");
 }
 
 } // namespace JSC
 }
 
 } // namespace JSC
index 0e1887c0f991835a998297b55346dd8bc79bf49c..cf236bf5e3f5df963f5d3c0465ffafcdee3286c4 100644 (file)
@@ -41,13 +41,6 @@ bool JSValue::strictEqualSlowCase(ExecState* exec, JSValue v1, JSValue v2)
     return strictEqualSlowCaseInline(exec, v1, v2);
 }
 
     return strictEqualSlowCaseInline(exec, v1, v2);
 }
 
-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()
 NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
 {
     // exception for the Date exception in defaultValue()
index c3aa0fa4f65a07302c7577dde378fce739699d94..122890247e1c3042dad8487290fd56a09de0af2e 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef Operations_h
 #define Operations_h
 
 #ifndef Operations_h
 #define Operations_h
 
+#include "ExceptionHelpers.h"
 #include "Interpreter.h"
 #include "JSImmediate.h"
 #include "JSNumberCell.h"
 #include "Interpreter.h"
 #include "JSImmediate.h"
 #include "JSNumberCell.h"
@@ -29,7 +30,6 @@
 
 namespace JSC {
 
 
 namespace JSC {
 
-    NEVER_INLINE JSValue throwOutOfMemoryError(ExecState*);
     NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
     JSValue jsTypeStringForValue(CallFrame*, JSValue);
     bool jsIsObjectType(JSValue);
     NEVER_INLINE JSValue jsAddSlowCase(CallFrame*, JSValue, JSValue);
     JSValue jsTypeStringForValue(CallFrame*, JSValue);
     bool jsIsObjectType(JSValue);
@@ -37,132 +37,203 @@ namespace JSC {
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
     {
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
     {
-        if (!s1->length())
+        unsigned length1 = s1->length();
+        if (!length1)
             return s2;
             return s2;
-        if (!s2->length())
+        unsigned length2 = s2->length();
+        if (!length2)
             return s1;
             return s1;
+        if ((length1 + length2) < length1)
+            return throwOutOfMemoryError(exec);
 
 
-        unsigned ropeLength = s1->ropeLength() + s2->ropeLength();
+        unsigned fiberCount = s1->size() + s2->size();
         JSGlobalData* globalData = &exec->globalData();
 
         JSGlobalData* globalData = &exec->globalData();
 
-        if (ropeLength <= JSString::s_maxInternalRopeLength)
-            return new (globalData) JSString(globalData, ropeLength, s1, s2);
+        if (fiberCount <= JSString::s_maxInternalRopeLength)
+            return new (globalData) JSString(globalData, fiberCount, s1, s2);
 
 
-        unsigned index = 0;
-        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
-        if (UNLIKELY(!rope))
+        JSString::RopeBuilder ropeBuilder(fiberCount);
+        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
             return throwOutOfMemoryError(exec);
             return throwOutOfMemoryError(exec);
-        rope->append(index, s1);
-        rope->append(index, s2);
-        ASSERT(index == ropeLength);
-        return new (globalData) JSString(globalData, rope.release());
+        ropeBuilder.append(s1);
+        ropeBuilder.append(s2);
+        return new (globalData) JSString(globalData, ropeBuilder.release());
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
     {
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
     {
-        unsigned ropeLength = 1 + s2->ropeLength();
+        unsigned length1 = u1.size();
+        if (!length1)
+            return s2;
+        unsigned length2 = s2->length();
+        if (!length2)
+            return jsString(exec, u1);
+        if ((length1 + length2) < length1)
+            return throwOutOfMemoryError(exec);
+
+        unsigned fiberCount = 1 + s2->size();
         JSGlobalData* globalData = &exec->globalData();
 
         JSGlobalData* globalData = &exec->globalData();
 
-        if (ropeLength <= JSString::s_maxInternalRopeLength)
-            return new (globalData) JSString(globalData, ropeLength, u1, s2);
+        if (fiberCount <= JSString::s_maxInternalRopeLength)
+            return new (globalData) JSString(globalData, fiberCount, u1, s2);
 
 
-        unsigned index = 0;
-        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
-        if (UNLIKELY(!rope))
+        JSString::RopeBuilder ropeBuilder(fiberCount);
+        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
             return throwOutOfMemoryError(exec);
             return throwOutOfMemoryError(exec);
-        rope->append(index, u1);
-        rope->append(index, s2);
-        ASSERT(index == ropeLength);
-        return new (globalData) JSString(globalData, rope.release());
+        ropeBuilder.append(u1);
+        ropeBuilder.append(s2);
+        return new (globalData) JSString(globalData, ropeBuilder.release());
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
     {
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
     {
-        unsigned ropeLength = s1->ropeLength() + 1;
+        unsigned length1 = s1->length();
+        if (!length1)
+            return jsString(exec, u2);
+        unsigned length2 = u2.size();
+        if (!length2)
+            return s1;
+        if ((length1 + length2) < length1)
+            return throwOutOfMemoryError(exec);
+
+        unsigned fiberCount = s1->size() + 1;
         JSGlobalData* globalData = &exec->globalData();
 
         JSGlobalData* globalData = &exec->globalData();
 
-        if (ropeLength <= JSString::s_maxInternalRopeLength)
-            return new (globalData) JSString(globalData, ropeLength, s1, u2);
+        if (fiberCount <= JSString::s_maxInternalRopeLength)
+            return new (globalData) JSString(globalData, fiberCount, s1, u2);
 
 
-        unsigned index = 0;
-        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
-        if (UNLIKELY(!rope))
+        JSString::RopeBuilder ropeBuilder(fiberCount);
+        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
             return throwOutOfMemoryError(exec);
             return throwOutOfMemoryError(exec);
-        rope->append(index, s1);
-        rope->append(index, u2);
-        ASSERT(index == ropeLength);
-        return new (globalData) JSString(globalData, rope.release());
+        ropeBuilder.append(s1);
+        ropeBuilder.append(u2);
+        return new (globalData) JSString(globalData, ropeBuilder.release());
+    }
+
+    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2)
+    {
+        unsigned length1 = u1.size();
+        if (!length1)
+            return jsString(exec, u2);
+        unsigned length2 = u2.size();
+        if (!length2)
+            return jsString(exec, u1);
+        if ((length1 + length2) < length1)
+            return throwOutOfMemoryError(exec);
+
+        JSGlobalData* globalData = &exec->globalData();
+        return new (globalData) JSString(globalData, u1, u2);
+    }
+
+    ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3)
+    {
+        unsigned length1 = u1.size();
+        unsigned length2 = u2.size();
+        unsigned length3 = u3.size();
+        if (!length1)
+            return jsString(exec, u2, u3);
+        if (!length2)
+            return jsString(exec, u1, u3);
+        if (!length3)
+            return jsString(exec, u1, u2);
+
+        if ((length1 + length2) < length1)
+            return throwOutOfMemoryError(exec);
+        if ((length1 + length2 + length3) < length3)
+            return throwOutOfMemoryError(exec);
+
+        JSGlobalData* globalData = &exec->globalData();
+        return new (globalData) JSString(globalData, u1, u2, u3);
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
     {
         ASSERT(count >= 3);
 
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
     {
         ASSERT(count >= 3);
 
-        unsigned ropeLength = 0;
+        unsigned fiberCount = 0;
         for (unsigned i = 0; i < count; ++i) {
             JSValue v = strings[i].jsValue();
             if (LIKELY(v.isString()))
         for (unsigned i = 0; i < count; ++i) {
             JSValue v = strings[i].jsValue();
             if (LIKELY(v.isString()))
-                ropeLength += asString(v)->ropeLength();
+                fiberCount += asString(v)->size();
             else
             else
-                ++ropeLength;
+                ++fiberCount;
         }
 
         JSGlobalData* globalData = &exec->globalData();
         }
 
         JSGlobalData* globalData = &exec->globalData();
-        if (ropeLength == 3)
+        if (fiberCount == 3)
             return new (globalData) JSString(exec, strings[0].jsValue(), strings[1].jsValue(), strings[2].jsValue());
 
             return new (globalData) JSString(exec, strings[0].jsValue(), strings[1].jsValue(), strings[2].jsValue());
 
-        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
-        if (UNLIKELY(!rope))
+        JSString::RopeBuilder ropeBuilder(fiberCount);
+        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
             return throwOutOfMemoryError(exec);
 
             return throwOutOfMemoryError(exec);
 
-        unsigned index = 0;
+        unsigned length = 0;
+        bool overflow = false;
+
         for (unsigned i = 0; i < count; ++i) {
             JSValue v = strings[i].jsValue();
             if (LIKELY(v.isString()))
         for (unsigned i = 0; i < count; ++i) {
             JSValue v = strings[i].jsValue();
             if (LIKELY(v.isString()))
-                rope->append(index, asString(v));
+                ropeBuilder.append(asString(v));
             else
             else
-                rope->append(index, v.toString(exec));
+                ropeBuilder.append(v.toString(exec));
+
+            unsigned newLength = ropeBuilder.length();
+            if (newLength < length)
+                overflow = true;
+            length = newLength;
         }
 
         }
 
-        ASSERT(index == ropeLength);
-        return new (globalData) JSString(globalData, rope.release());
+        if (overflow)
+            return throwOutOfMemoryError(exec);
+
+        return new (globalData) JSString(globalData, ropeBuilder.release());
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args)
     {
     }
 
     ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args)
     {
-        unsigned ropeLength = 0;
+        unsigned fiberCount = 0;
         if (LIKELY(thisValue.isString()))
         if (LIKELY(thisValue.isString()))
-            ropeLength += asString(thisValue)->ropeLength();
+            fiberCount += asString(thisValue)->size();
         else
         else
-            ++ropeLength;
+            ++fiberCount;
         for (unsigned i = 0; i < args.size(); ++i) {
             JSValue v = args.at(i);
             if (LIKELY(v.isString()))
         for (unsigned i = 0; i < args.size(); ++i) {
             JSValue v = args.at(i);
             if (LIKELY(v.isString()))
-                ropeLength += asString(v)->ropeLength();
+                fiberCount += asString(v)->size();
             else
             else
-                ++ropeLength;
+                ++fiberCount;
         }
 
         }
 
-        RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
-        if (UNLIKELY(!rope))
+        JSString::RopeBuilder ropeBuilder(fiberCount);
+        if (UNLIKELY(ropeBuilder.isOutOfMemory()))
             return throwOutOfMemoryError(exec);
 
             return throwOutOfMemoryError(exec);
 
-        unsigned index = 0;
         if (LIKELY(thisValue.isString()))
         if (LIKELY(thisValue.isString()))
-            rope->append(index, asString(thisValue));
+            ropeBuilder.append(asString(thisValue));
         else
         else
-            rope->append(index, thisValue.toString(exec));
+            ropeBuilder.append(thisValue.toString(exec));
+
+        unsigned length = 0;
+        bool overflow = false;
+
         for (unsigned i = 0; i < args.size(); ++i) {
             JSValue v = args.at(i);
             if (LIKELY(v.isString()))
         for (unsigned i = 0; i < args.size(); ++i) {
             JSValue v = args.at(i);
             if (LIKELY(v.isString()))
-                rope->append(index, asString(v));
+                ropeBuilder.append(asString(v));
             else
             else
-                rope->append(index, v.toString(exec));
+                ropeBuilder.append(v.toString(exec));
+
+            unsigned newLength = ropeBuilder.length();
+            if (newLength < length)
+                overflow = true;
+            length = newLength;
         }
         }
-        ASSERT(index == ropeLength);
+
+        if (overflow)
+            return throwOutOfMemoryError(exec);
 
         JSGlobalData* globalData = &exec->globalData();
 
         JSGlobalData* globalData = &exec->globalData();
-        return new (globalData) JSString(globalData, rope.release());
+        return new (globalData) JSString(globalData, ropeBuilder.release());
     }
 
     // ECMA 11.9.3
     }
 
     // ECMA 11.9.3
index 5108272fd398152024933b2281e2562074808781..6b246691ba24af4b596cdbd2e719a271d480998f 100644 (file)
@@ -30,7 +30,7 @@ static const size_t setThreshold = 20;
 
 void PropertyNameArray::add(UString::Rep* identifier)
 {
 
 void PropertyNameArray::add(UString::Rep* identifier)
 {
-    ASSERT(identifier == &UString::Rep::null() || identifier == &UString::Rep::empty() || identifier->isIdentifier());
+    ASSERT(identifier == UString::null().rep() || identifier == UString::Rep::empty() || identifier->isIdentifier());
 
     size_t size = m_data->propertyNameVector().size();
     if (size < setThreshold) {
 
     size_t size = m_data->propertyNameVector().size();
     if (size < setThreshold) {
index a0a2f48f9c5c1d9334ec4c88eae3702cf17152ca..2306a11e576fe820501be6e3537c517af7e1474f 100644 (file)
 
 namespace JSC {
 
 
 namespace JSC {
 
-JSValue PropertySlot::functionGetter(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue PropertySlot::functionGetter(ExecState* exec) const
 {
     // Prevent getter functions from observing execution if an exception is pending.
     if (exec->hadException())
         return exec->exception();
 
     CallData callData;
 {
     // Prevent getter functions from observing execution if an exception is pending.
     if (exec->hadException())
         return exec->exception();
 
     CallData callData;
-    CallType callType = slot.m_data.getterFunc->getCallData(callData);
+    CallType callType = m_data.getterFunc->getCallData(callData);
     if (callType == CallTypeHost)
     if (callType == CallTypeHost)
-        return callData.native.function(exec, slot.m_data.getterFunc, slot.slotBase(), exec->emptyList());
+        return callData.native.function(exec, m_data.getterFunc, thisValue(), exec->emptyList());
     ASSERT(callType == CallTypeJS);
     // FIXME: Can this be done more efficiently using the callData?
     ASSERT(callType == CallTypeJS);
     // FIXME: Can this be done more efficiently using the callData?
-    return asFunction(slot.m_data.getterFunc)->call(exec, slot.slotBase(), exec->emptyList());
+    return asFunction(m_data.getterFunc)->call(exec, thisValue(), exec->emptyList());
 }
 
 } // namespace JSC
 }
 
 } // namespace JSC
index 15d90342ae7d401939239ba19b08ac09aae79fd7..de9ddc99822a633f024e96362188d9d5c4ab6bc0 100644 (file)
@@ -34,10 +34,20 @@ namespace JSC {
 
 #define JSC_VALUE_SLOT_MARKER 0
 #define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
 
 #define JSC_VALUE_SLOT_MARKER 0
 #define JSC_REGISTER_SLOT_MARKER reinterpret_cast<GetValueFunc>(1)
+#define INDEX_GETTER_MARKER reinterpret_cast<GetValueFunc>(2)
+#define GETTER_FUNCTION_MARKER reinterpret_cast<GetValueFunc>(3)
 
     class PropertySlot {
     public:
 
     class PropertySlot {
     public:
+        enum CachedPropertyType {
+            Uncacheable,
+            Getter,
+            Custom,
+            Value
+        };
+
         PropertySlot()
         PropertySlot()
+            : m_cachedPropertyType(Uncacheable)
         {
             clearBase();
             clearOffset();
         {
             clearBase();
             clearOffset();
@@ -46,12 +56,14 @@ namespace JSC {
 
         explicit PropertySlot(const JSValue base)
             : m_slotBase(base)
 
         explicit PropertySlot(const JSValue base)
             : m_slotBase(base)
+            , m_cachedPropertyType(Uncacheable)
         {
             clearOffset();
             clearValue();
         }
 
         {
             clearOffset();
             clearValue();
         }
 
-        typedef JSValue (*GetValueFunc)(ExecState*, const Identifier&, const PropertySlot&);
+        typedef JSValue (*GetValueFunc)(ExecState*, JSValue slotBase, const Identifier&);
+        typedef JSValue (*GetIndexValueFunc)(ExecState*, JSValue slotBase, unsigned);
 
         JSValue getValue(ExecState* exec, const Identifier& propertyName) const
         {
 
         JSValue getValue(ExecState* exec, const Identifier& propertyName) const
         {
@@ -59,7 +71,11 @@ namespace JSC {
                 return *m_data.valueSlot;
             if (m_getValue == JSC_REGISTER_SLOT_MARKER)
                 return (*m_data.registerSlot).jsValue();
                 return *m_data.valueSlot;
             if (m_getValue == JSC_REGISTER_SLOT_MARKER)
                 return (*m_data.registerSlot).jsValue();
-            return m_getValue(exec, propertyName, *this);
+            if (m_getValue == INDEX_GETTER_MARKER)
+                return m_getIndexValue(exec, slotBase(), index());
+            if (m_getValue == GETTER_FUNCTION_MARKER)
+                return functionGetter(exec);
+            return m_getValue(exec, slotBase(), propertyName);
         }
 
         JSValue getValue(ExecState* exec, unsigned propertyName) const
         }
 
         JSValue getValue(ExecState* exec, unsigned propertyName) const
@@ -68,10 +84,16 @@ namespace JSC {
                 return *m_data.valueSlot;
             if (m_getValue == JSC_REGISTER_SLOT_MARKER)
                 return (*m_data.registerSlot).jsValue();
                 return *m_data.valueSlot;
             if (m_getValue == JSC_REGISTER_SLOT_MARKER)
                 return (*m_data.registerSlot).jsValue();
-            return m_getValue(exec, Identifier::from(exec, propertyName), *this);
+            if (m_getValue == INDEX_GETTER_MARKER)
+                return m_getIndexValue(exec, m_slotBase, m_data.index);
+            if (m_getValue == GETTER_FUNCTION_MARKER)
+                return functionGetter(exec);
+            return m_getValue(exec, slotBase(), Identifier::from(exec, propertyName));
         }
 
         }
 
-        bool isCacheable() const { return m_offset != WTF::notFound; }
+        CachedPropertyType cachedPropertyType() const { return m_cachedPropertyType; }
+        bool isCacheable() const { return m_cachedPropertyType != Uncacheable; }
+        bool isCacheableValue() const { return m_cachedPropertyType == Value; }
         size_t cachedOffset() const
         {
             ASSERT(isCacheable());
         size_t cachedOffset() const
         {
             ASSERT(isCacheable());
@@ -102,6 +124,7 @@ namespace JSC {
             m_slotBase = slotBase;
             m_data.valueSlot = valueSlot;
             m_offset = offset;
             m_slotBase = slotBase;
             m_data.valueSlot = valueSlot;
             m_offset = offset;
+            m_cachedPropertyType = Value;
         }
         
         void setValue(JSValue value)
         }
         
         void setValue(JSValue value)
@@ -128,25 +151,49 @@ namespace JSC {
             ASSERT(slotBase);
             ASSERT(getValue);
             m_getValue = getValue;
             ASSERT(slotBase);
             ASSERT(getValue);
             m_getValue = getValue;
+            m_getIndexValue = 0;
             m_slotBase = slotBase;
         }
             m_slotBase = slotBase;
         }
-
-        void setCustomIndex(JSValue slotBase, unsigned index, GetValueFunc getValue)
+        
+        void setCacheableCustom(JSValue slotBase, GetValueFunc getValue)
         {
             ASSERT(slotBase);
             ASSERT(getValue);
             m_getValue = getValue;
         {
             ASSERT(slotBase);
             ASSERT(getValue);
             m_getValue = getValue;
+            m_getIndexValue = 0;
+            m_slotBase = slotBase;
+            m_cachedPropertyType = Custom;
+        }
+
+        void setCustomIndex(JSValue slotBase, unsigned index, GetIndexValueFunc getIndexValue)
+        {
+            ASSERT(slotBase);
+            ASSERT(getIndexValue);
+            m_getValue = INDEX_GETTER_MARKER;
+            m_getIndexValue = getIndexValue;
             m_slotBase = slotBase;
             m_data.index = index;
         }
             m_slotBase = slotBase;
             m_data.index = index;
         }
-        
+
         void setGetterSlot(JSObject* getterFunc)
         {
             ASSERT(getterFunc);
         void setGetterSlot(JSObject* getterFunc)
         {
             ASSERT(getterFunc);
-            m_getValue = functionGetter;
+            m_thisValue = m_slotBase;
+            m_getValue = GETTER_FUNCTION_MARKER;
             m_data.getterFunc = getterFunc;
         }
             m_data.getterFunc = getterFunc;
         }
-        
+
+        void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, unsigned offset)
+        {
+            ASSERT(getterFunc);
+            m_getValue = GETTER_FUNCTION_MARKER;
+            m_thisValue = m_slotBase;
+            m_slotBase = slotBase;
+            m_data.getterFunc = getterFunc;
+            m_offset = offset;
+            m_cachedPropertyType = Getter;
+        }
+
         void setUndefined()
         {
             setValue(jsUndefined());
         void setUndefined()
         {
             setValue(jsUndefined());
@@ -182,15 +229,24 @@ namespace JSC {
         {
             // 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.)
         {
             // 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;
+            m_offset = 0;
+            m_cachedPropertyType = Uncacheable;
         }
 
         unsigned index() const { return m_data.index; }
 
         }
 
         unsigned index() const { return m_data.index; }
 
+        JSValue thisValue() const { return m_thisValue; }
+
+        GetValueFunc customGetter() const
+        {
+            ASSERT(m_cachedPropertyType == Custom);
+            return m_getValue;
+        }
     private:
     private:
-        static JSValue functionGetter(ExecState*, const Identifier&, const PropertySlot&);
+        JSValue functionGetter(ExecState*) const;
 
         GetValueFunc m_getValue;
 
         GetValueFunc m_getValue;
+        GetIndexValueFunc m_getIndexValue;
         
         JSValue m_slotBase;
         union {
         
         JSValue m_slotBase;
         union {
@@ -201,8 +257,10 @@ namespace JSC {
         } m_data;
 
         JSValue m_value;
         } m_data;
 
         JSValue m_value;
+        JSValue m_thisValue;
 
         size_t m_offset;
 
         size_t m_offset;
+        CachedPropertyType m_cachedPropertyType;
     };
 
 } // namespace JSC
     };
 
 } // namespace JSC
index 4e958f49d5943127e1e9ed58f29713cf07101358..59f1f87f7747570ef4b2e1842d6bda3bedd4d5ac 100644 (file)
 
 #else
 
 
 #else
 
-#if ENABLE(WREC)
-#include "JIT.h"
-#include "WRECGenerator.h"
-#endif
 #include <pcre/pcre.h>
 
 #endif
 
 namespace JSC {
 
 #include <pcre/pcre.h>
 
 #endif
 
 namespace JSC {
 
-#if ENABLE(WREC)
-using namespace WREC;
-#endif
-
 inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
     : m_pattern(pattern)
     , m_flagBits(0)
     , m_constructionError(0)
     , m_numSubpatterns(0)
 inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern)
     : m_pattern(pattern)
     , m_flagBits(0)
     , m_constructionError(0)
     , m_numSubpatterns(0)
+    , m_lastMatchStart(-1)
 {
     compile(globalData);
 }
 {
     compile(globalData);
 }
@@ -68,14 +61,15 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const US
     , m_flagBits(0)
     , m_constructionError(0)
     , m_numSubpatterns(0)
     , m_flagBits(0)
     , m_constructionError(0)
     , m_numSubpatterns(0)
+    , m_lastMatchStart(-1)
 {
     // NOTE: The global flag is handled on a case-by-case basis by functions like
     // String::match and RegExpObject::match.
 {
     // NOTE: The global flag is handled on a case-by-case basis by functions like
     // String::match and RegExpObject::match.
-    if (flags.find('g') != -1)
+    if (flags.find('g') != UString::NotFound)
         m_flagBits |= Global;
         m_flagBits |= Global;
-    if (flags.find('i') != -1)
+    if (flags.find('i') != UString::NotFound)
         m_flagBits |= IgnoreCase;
         m_flagBits |= IgnoreCase;
-    if (flags.find('m') != -1)
+    if (flags.find('m') != UString::NotFound)
         m_flagBits |= Multiline;
 
     compile(globalData);
         m_flagBits |= Multiline;
 
     compile(globalData);
@@ -117,8 +111,24 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
     if (ovector)
         ovector->clear();
 
     if (ovector)
         ovector->clear();
 
-    if (startOffset > s.size() || s.isNull())
+    if (static_cast<unsigned>(startOffset) > s.size() || s.isNull()) {
+        m_lastMatchString = UString();
+        m_lastMatchStart = -1;
+        m_lastOVector.shrink(0);
         return -1;
         return -1;
+    }
+    
+    // Perform check to see if this match call is the same as the last match invocation
+    // and if it is return the prior result.
+    if ((startOffset == m_lastMatchStart) && (s.rep() == m_lastMatchString.rep())) {
+        if (ovector)
+            *ovector = m_lastOVector;
+        
+        if (m_lastOVector.isEmpty())
+            return -1;
+
+        return m_lastOVector.at(0);
+    }
 
 #if ENABLE(YARR_JIT)
     if (!!m_regExpJITCode) {
 
 #if ENABLE(YARR_JIT)
     if (!!m_regExpJITCode) {
@@ -156,26 +166,30 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
             if (ovector)
                 ovector->clear();
         }
             if (ovector)
                 ovector->clear();
         }
+        
+        m_lastMatchString = s;
+        m_lastMatchStart = startOffset;
+
+        if (ovector)
+            m_lastOVector = *ovector;
+        else
+            m_lastOVector = nonReturnedOvector;
+
         return result;
     }
 
         return result;
     }
 
+    m_lastMatchString = UString();
+    m_lastMatchStart = -1;
+    m_lastOVector.shrink(0);
+
     return -1;
 }
 
 #else
 
     return -1;
 }
 
 #else
 
-void RegExp::compile(JSGlobalData* globalData)
+void RegExp::compile(JSGlobalData*)
 {
     m_regExp = 0;
 {
     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);
     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);
@@ -188,39 +202,9 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
     if (ovector)
         ovector->clear();
 
     if (ovector)
         ovector->clear();
 
-    if (startOffset > s.size() || s.isNull())
+    if (static_cast<unsigned>(startOffset) > s.size() || s.isNull())
         return -1;
 
         return -1;
 
-#if ENABLE(WREC)
-    if (m_wrecFunction) {
-        int offsetVectorSize = (m_numSubpatterns + 1) * 2;
-        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;
-
-        int result = m_wrecFunction(s.data(), startOffset, s.size(), offsetVector);
-
-        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;
-    } else
-#endif
     if (m_regExp) {
         // Set up the offset vector for the result.
         // First 2/3 used for result, the last third used by PCRE.
     if (m_regExp) {
         // Set up the offset vector for the result.
         // First 2/3 used for result, the last third used by PCRE.
index 61ab0bc284d17a15242936fbe3969b3a2b26f0be..04022bc9563850f2a1bb2499e066993523a2c12a 100644 (file)
@@ -23,7 +23,6 @@
 #define RegExp_h
 
 #include "UString.h"
 #define RegExp_h
 
 #include "UString.h"
-#include "WREC.h"
 #include "ExecutableAllocator.h"
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
 #include "ExecutableAllocator.h"
 #include <wtf/Forward.h>
 #include <wtf/RefCounted.h>
@@ -68,16 +67,15 @@ namespace JSC {
         int m_flagBits;
         const char* m_constructionError;
         unsigned m_numSubpatterns;
         int m_flagBits;
         const char* m_constructionError;
         unsigned m_numSubpatterns;
+        UString m_lastMatchString;
+        int m_lastMatchStart;
+        Vector<int, 32> m_lastOVector;
 
 #if ENABLE(YARR_JIT)
         Yarr::RegexCodeBlock m_regExpJITCode;
 #elif ENABLE(YARR)
         OwnPtr<Yarr::BytecodePattern> m_regExpBytecode;
 #else
 
 #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
     };
         JSRegExp* m_regExp;
 #endif
     };
diff --git a/runtime/RegExpCache.cpp b/runtime/RegExpCache.cpp
new file mode 100644 (file)
index 0000000..192df4d
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Renata Hodovan (hodovan@inf.u-szeged.hu)
+ * 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.
+ */
+
+#include "config.h"
+
+#include "RegExpCache.h"
+
+namespace JSC {
+
+PassRefPtr<RegExp> RegExpCache::lookupOrCreate(const UString& patternString, const UString& flags)
+{
+    if (patternString.size() < maxCacheablePatternLength) {
+        pair<HashMap<RegExpKey, RefPtr<RegExp> >::iterator, bool> result = m_cacheMap.add(RegExpKey(flags, patternString), 0);
+        if (!result.second)
+            return result.first->second;
+    }
+    return create(patternString, flags);
+}
+
+PassRefPtr<RegExp> RegExpCache::create(const UString& patternString, const UString& flags) 
+{
+    RefPtr<RegExp> regExp;
+
+    if (!flags.isNull())
+        regExp = RegExp::create(m_globalData, patternString, flags);
+    else
+        regExp = RegExp::create(m_globalData, patternString);
+
+    if (patternString.size() >= maxCacheablePatternLength)
+        return regExp;
+
+    ++m_nextKeyToEvict;
+    if (m_nextKeyToEvict == maxCacheableEntries) {
+        m_nextKeyToEvict = 0;
+        m_isFull = true;
+    }
+    if (m_isFull)
+        m_cacheMap.remove(RegExpKey(patternKeyArray[m_nextKeyToEvict].flagsValue, patternKeyArray[m_nextKeyToEvict].pattern));
+
+    RegExpKey key = RegExpKey(flags, patternString);
+    m_cacheMap.set(key, regExp);
+    patternKeyArray[m_nextKeyToEvict].flagsValue = key.flagsValue;
+    patternKeyArray[m_nextKeyToEvict].pattern = patternString.rep();
+    return regExp;
+}
+
+RegExpCache::RegExpCache(JSGlobalData* globalData)
+    : m_globalData(globalData)
+    , m_nextKeyToEvict(-1)
+    , m_isFull(false)
+{
+}
+
+}
diff --git a/runtime/RegExpCache.h b/runtime/RegExpCache.h
new file mode 100644 (file)
index 0000000..03b73ac
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Renata Hodovan (hodovan@inf.u-szeged.hu)
+ * 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.
+ */
+
+#include "RegExp.h"
+#include "RegExpKey.h"
+#include "UString.h"
+
+#ifndef RegExpCache_h
+#define RegExpCache_h
+
+namespace JSC {
+
+class RegExpCache {
+public:
+    PassRefPtr<RegExp> lookupOrCreate(const UString& patternString, const UString& flags);
+    PassRefPtr<RegExp> create(const UString& patternString, const UString& flags);
+    RegExpCache(JSGlobalData* globalData);
+
+private:
+    static const unsigned maxCacheablePatternLength = 256;
+    static const int maxCacheableEntries = 256;
+
+    typedef HashMap<RegExpKey, RefPtr<RegExp> > RegExpCacheMap;
+    RegExpKey patternKeyArray[maxCacheableEntries];
+    RegExpCacheMap m_cacheMap;
+    JSGlobalData* m_globalData;
+    int m_nextKeyToEvict;
+    bool m_isFull;
+};
+
+} // namespace JSC
+
+#endif // RegExpCache_h
index 6f001429200cedb40264fc0448d701dec7209b4f..5332a874f74438f1ef162e8aaac794bfcb5b3aa2 100644 (file)
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSString.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSString.h"
+#include "Lookup.h"
 #include "ObjectPrototype.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpObject.h"
 #include "RegExpPrototype.h"
 #include "RegExp.h"
 #include "ObjectPrototype.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpObject.h"
 #include "RegExpPrototype.h"
 #include "RegExp.h"
+#include "RegExpCache.h"
 
 namespace JSC {
 
 
 namespace JSC {
 
-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 JSValue regExpConstructorInput(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorMultiline(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorLastMatch(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorLastParen(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorLeftContext(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorRightContext(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar1(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar2(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar3(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar4(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar5(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar6(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar7(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar8(ExecState*, JSValue, const Identifier&);
+static JSValue regExpConstructorDollar9(ExecState*, JSValue, const Identifier&);
 
 static void setRegExpConstructorInput(ExecState*, JSObject*, JSValue);
 static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue);
 
 static void setRegExpConstructorInput(ExecState*, JSObject*, JSValue);
 static void setRegExpConstructorMultiline(ExecState*, JSObject*, JSValue);
@@ -113,17 +115,17 @@ RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate
     memcpy(d->lastOvector().data(), data->lastOvector().data(), offsetVectorSize * sizeof(int));
     // d->multiline is not needed, and remains uninitialized
 
     memcpy(d->lastOvector().data(), data->lastOvector().data(), offsetVectorSize * sizeof(int));
     // d->multiline is not needed, and remains uninitialized
 
-    setLazyCreationData(d);
+    setSubclassData(d);
 }
 
 RegExpMatchesArray::~RegExpMatchesArray()
 {
 }
 
 RegExpMatchesArray::~RegExpMatchesArray()
 {
-    delete static_cast<RegExpConstructorPrivate*>(lazyCreationData());
+    delete static_cast<RegExpConstructorPrivate*>(subclassData());
 }
 
 void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
 {
 }
 
 void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
 {
-    RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(lazyCreationData());
+    RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(subclassData());
     ASSERT(d);
 
     unsigned lastNumSubpatterns = d->lastNumSubPatterns;
     ASSERT(d);
 
     unsigned lastNumSubpatterns = d->lastNumSubPatterns;
@@ -141,7 +143,7 @@ void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
     JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot);
 
     delete d;
     JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot);
 
     delete d;
-    setLazyCreationData(0);
+    setSubclassData(0);
 }
 
 JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
 }
 
 JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
@@ -195,79 +197,79 @@ bool RegExpConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifi
     return getStaticValueDescriptor<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, descriptor);
 }
 
     return getStaticValueDescriptor<RegExpConstructor, InternalFunction>(exec, ExecState::regExpConstructorTable(exec), this, propertyName, descriptor);
 }
 
-JSValue regExpConstructorDollar1(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar1(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 1);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 1);
 }
 
 }
 
-JSValue regExpConstructorDollar2(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar2(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 2);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 2);
 }
 
 }
 
-JSValue regExpConstructorDollar3(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar3(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 3);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 3);
 }
 
 }
 
-JSValue regExpConstructorDollar4(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar4(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 4);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 4);
 }
 
 }
 
-JSValue regExpConstructorDollar5(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar5(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 5);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 5);
 }
 
 }
 
-JSValue regExpConstructorDollar6(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar6(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 6);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 6);
 }
 
 }
 
-JSValue regExpConstructorDollar7(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar7(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 7);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 7);
 }
 
 }
 
-JSValue regExpConstructorDollar8(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar8(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 8);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 8);
 }
 
 }
 
-JSValue regExpConstructorDollar9(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorDollar9(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 9);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 9);
 }
 
 }
 
-JSValue regExpConstructorInput(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorInput(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return jsString(exec, asRegExpConstructor(slot.slotBase())->input());
+    return jsString(exec, asRegExpConstructor(slotBase)->input());
 }
 
 }
 
-JSValue regExpConstructorMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorMultiline(ExecState*, JSValue slotBase, const Identifier&)
 {
 {
-    return jsBoolean(asRegExpConstructor(slot.slotBase())->multiline());
+    return jsBoolean(asRegExpConstructor(slotBase)->multiline());
 }
 
 }
 
-JSValue regExpConstructorLastMatch(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLastMatch(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getBackref(exec, 0);
+    return asRegExpConstructor(slotBase)->getBackref(exec, 0);
 }
 
 }
 
-JSValue regExpConstructorLastParen(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLastParen(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getLastParen(exec);
+    return asRegExpConstructor(slotBase)->getLastParen(exec);
 }
 
 }
 
-JSValue regExpConstructorLeftContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorLeftContext(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getLeftContext(exec);
+    return asRegExpConstructor(slotBase)->getLeftContext(exec);
 }
 
 }
 
-JSValue regExpConstructorRightContext(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpConstructorRightContext(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return asRegExpConstructor(slot.slotBase())->getRightContext(exec);
+    return asRegExpConstructor(slotBase)->getRightContext(exec);
 }
 
 void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 }
 
 void RegExpConstructor::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
@@ -300,7 +302,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
     UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec);
     UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
 
     UString pattern = arg0.isUndefined() ? UString("") : arg0.toString(exec);
     UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
 
-    RefPtr<RegExp> regExp = RegExp::create(&exec->globalData(), pattern, flags);
+    RefPtr<RegExp> regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
     if (!regExp->isValid())
         return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
     return new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
     if (!regExp->isValid())
         return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
     return new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
diff --git a/runtime/RegExpKey.h b/runtime/RegExpKey.h
new file mode 100644 (file)
index 0000000..e5ab438
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 University of Szeged
+ * Copyright (C) 2010 Renata Hodovan (hodovan@inf.u-szeged.hu)
+ * 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.
+ */
+
+#include "UString.h"
+
+#ifndef RegExpKey_h
+#define RegExpKey_h
+
+namespace JSC {
+
+struct RegExpKey {
+    int flagsValue;
+    RefPtr<UString::Rep> pattern;
+
+    RegExpKey()
+        : flagsValue(0)
+    {
+    }
+
+    RegExpKey(int flags)
+        : flagsValue(flags)
+    {
+    }
+
+    RegExpKey(int flags, const UString& pattern)
+        : flagsValue(flags)
+        , pattern(pattern.rep())
+    {
+    }
+
+    RegExpKey(int flags, const PassRefPtr<UString::Rep> pattern)
+        : flagsValue(flags)
+        , pattern(pattern)
+    {
+    }
+
+    RegExpKey(const UString& flags, const UString& pattern)
+        : pattern(pattern.rep())
+    {
+        flagsValue = getFlagsValue(flags);
+    }
+
+    int getFlagsValue(const UString flags) 
+    {
+        flagsValue = 0;
+        if (flags.find('g') != UString::NotFound)
+            flagsValue += 4;
+        if (flags.find('i') != UString::NotFound)
+            flagsValue += 2;
+        if (flags.find('m') != UString::NotFound)
+            flagsValue += 1;
+        return flagsValue;
+    }
+};
+} // namespace JSC
+
+namespace WTF {
+template<typename T> struct DefaultHash;
+template<typename T> struct RegExpHash;
+
+inline bool operator==(const JSC::RegExpKey& a, const JSC::RegExpKey& b) 
+{
+    if (a.flagsValue != b.flagsValue)
+        return false;
+    if (!a.pattern)
+        return !b.pattern;
+    if (!b.pattern)
+        return false;
+    return equal(a.pattern.get(), b.pattern.get());
+}
+
+template<> struct RegExpHash<JSC::RegExpKey> {
+    static unsigned hash(const JSC::RegExpKey& key) { return key.pattern->hash(); }
+    static bool equal(const JSC::RegExpKey& a, const JSC::RegExpKey& b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+template<> struct DefaultHash<JSC::RegExpKey> {
+    typedef RegExpHash<JSC::RegExpKey> Hash;
+};
+
+template<> struct HashTraits<JSC::RegExpKey> : GenericHashTraits<JSC::RegExpKey> {
+    static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = -1; }
+    static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == -1; }
+};
+} // namespace WTF
+
+#endif // RegExpKey_h
index 38d3cb4495733d3cd9e0bba2fcdb187f87e33356..b82362156350d3031622edf2c3ea822024ebbb18 100644 (file)
@@ -32,56 +32,56 @@ namespace JSC {
     private:
         virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
         {
     private:
         virtual bool getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
         {
-            if (lazyCreationData())
+            if (subclassData())
                 fillArrayInstance(exec);
             return JSArray::getOwnPropertySlot(exec, propertyName, slot);
         }
 
         virtual bool getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
         {
                 fillArrayInstance(exec);
             return JSArray::getOwnPropertySlot(exec, propertyName, slot);
         }
 
         virtual bool getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
         {
-            if (lazyCreationData())
+            if (subclassData())
                 fillArrayInstance(exec);
             return JSArray::getOwnPropertySlot(exec, propertyName, slot);
         }
 
         virtual bool getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
         {
                 fillArrayInstance(exec);
             return JSArray::getOwnPropertySlot(exec, propertyName, slot);
         }
 
         virtual bool getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
         {
-            if (lazyCreationData())
+            if (subclassData())
                 fillArrayInstance(exec);
             return JSArray::getOwnPropertyDescriptor(exec, propertyName, descriptor);
         }
 
         virtual void put(ExecState* exec, const Identifier& propertyName, JSValue v, PutPropertySlot& slot)
         {
                 fillArrayInstance(exec);
             return JSArray::getOwnPropertyDescriptor(exec, propertyName, descriptor);
         }
 
         virtual void put(ExecState* exec, const Identifier& propertyName, JSValue v, PutPropertySlot& slot)
         {
-            if (lazyCreationData())
+            if (subclassData())
                 fillArrayInstance(exec);
             JSArray::put(exec, propertyName, v, slot);
         }
 
         virtual void put(ExecState* exec, unsigned propertyName, JSValue v)
         {
                 fillArrayInstance(exec);
             JSArray::put(exec, propertyName, v, slot);
         }
 
         virtual void put(ExecState* exec, unsigned propertyName, JSValue v)
         {
-            if (lazyCreationData())
+            if (subclassData())
                 fillArrayInstance(exec);
             JSArray::put(exec, propertyName, v);
         }
 
         virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName)
         {
                 fillArrayInstance(exec);
             JSArray::put(exec, propertyName, v);
         }
 
         virtual bool deleteProperty(ExecState* exec, const Identifier& propertyName)
         {
-            if (lazyCreationData())
+            if (subclassData())
                 fillArrayInstance(exec);
             return JSArray::deleteProperty(exec, propertyName);
         }
 
         virtual bool deleteProperty(ExecState* exec, unsigned propertyName)
         {
                 fillArrayInstance(exec);
             return JSArray::deleteProperty(exec, propertyName);
         }
 
         virtual bool deleteProperty(ExecState* exec, unsigned propertyName)
         {
-            if (lazyCreationData())
+            if (subclassData())
                 fillArrayInstance(exec);
             return JSArray::deleteProperty(exec, propertyName);
         }
 
         virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
         {
                 fillArrayInstance(exec);
             return JSArray::deleteProperty(exec, propertyName);
         }
 
         virtual void getOwnPropertyNames(ExecState* exec, PropertyNameArray& arr, EnumerationMode mode = ExcludeDontEnumProperties)
         {
-            if (lazyCreationData())
+            if (subclassData())
                 fillArrayInstance(exec);
             JSArray::getOwnPropertyNames(exec, arr, mode);
         }
                 fillArrayInstance(exec);
             JSArray::getOwnPropertyNames(exec, arr, mode);
         }
index 42bfceffbc9c705ed0caae23be2e0c42c73c27eb..bc74924d0dba433523627b8b463404b75c049441 100644 (file)
 #include "JSArray.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
 #include "JSArray.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
+#include "Lookup.h"
 #include "RegExpConstructor.h"
 #include "RegExpPrototype.h"
 
 namespace JSC {
 
 #include "RegExpConstructor.h"
 #include "RegExpPrototype.h"
 
 namespace JSC {
 
-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 JSValue regExpObjectGlobal(ExecState*, JSValue, const Identifier&);
+static JSValue regExpObjectIgnoreCase(ExecState*, JSValue, const Identifier&);
+static JSValue regExpObjectMultiline(ExecState*, JSValue, const Identifier&);
+static JSValue regExpObjectSource(ExecState*, JSValue, const Identifier&);
+static JSValue regExpObjectLastIndex(ExecState*, JSValue, const Identifier&);
 static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue);
 
 } // namespace JSC
 static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue);
 
 } // namespace JSC
@@ -77,29 +78,29 @@ bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& p
     return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor);
 }
 
     return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor);
 }
 
-JSValue regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectGlobal(ExecState*, JSValue slotBase, const Identifier&)
 {
 {
-    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global());
+    return jsBoolean(asRegExpObject(slotBase)->regExp()->global());
 }
 
 }
 
-JSValue regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectIgnoreCase(ExecState*, JSValue slotBase, const Identifier&)
 {
 {
-    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->ignoreCase());
+    return jsBoolean(asRegExpObject(slotBase)->regExp()->ignoreCase());
 }
  
 }
  
-JSValue regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectMultiline(ExecState*, JSValue slotBase, const Identifier&)
 {            
 {            
-    return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->multiline());
+    return jsBoolean(asRegExpObject(slotBase)->regExp()->multiline());
 }
 
 }
 
-JSValue regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return jsString(exec, asRegExpObject(slot.slotBase())->regExp()->pattern());
+    return jsString(exec, asRegExpObject(slotBase)->regExp()->pattern());
 }
 
 }
 
-JSValue regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
+JSValue regExpObjectLastIndex(ExecState* exec, JSValue slotBase, const Identifier&)
 {
 {
-    return jsNumber(exec, asRegExpObject(slot.slotBase())->lastIndex());
+    return jsNumber(exec, asRegExpObject(slotBase)->lastIndex());
 }
 
 void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 }
 
 void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
index 5f9d3575e98e0ec7060c80b0bc45c010cb73aaaf..7c34b21a4d8811cafa3f744e2286fc63c53ae5e0 100644 (file)
 #include "JSFunction.h"
 #include "JSObject.h"
 #include "JSString.h"
 #include "JSFunction.h"
 #include "JSObject.h"
 #include "JSString.h"
+#include "JSStringBuilder.h"
 #include "JSValue.h"
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
 #include "RegExpObject.h"
 #include "RegExp.h"
 #include "JSValue.h"
 #include "ObjectPrototype.h"
 #include "PrototypeFunction.h"
 #include "RegExpObject.h"
 #include "RegExp.h"
+#include "RegExpCache.h"
 
 namespace JSC {
 
 
 namespace JSC {
 
@@ -87,7 +89,7 @@ JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue
     } else {
         UString pattern = args.isEmpty() ? UString("") : arg0.toString(exec);
         UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
     } else {
         UString pattern = args.isEmpty() ? UString("") : arg0.toString(exec);
         UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec);
-        regExp = RegExp::create(&exec->globalData(), pattern, flags);
+        regExp = exec->globalData().regExpCache()->lookupOrCreate(pattern, flags);
     }
 
     if (!regExp->isValid())
     }
 
     if (!regExp->isValid())
@@ -116,7 +118,7 @@ JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValu
         postfix[index] = 'm';
     UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
     // If source is empty, use "/(?:)/" to avoid colliding with comment syntax
         postfix[index] = 'm';
     UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
     // If source is empty, use "/(?:)/" to avoid colliding with comment syntax
-    return jsNontrivialString(exec, makeString("/", source.size() ? source : UString("(?:)"), postfix));
+    return jsMakeNontrivialString(exec, "/", source.size() ? source : UString("(?:)"), postfix);
 }
 
 } // namespace JSC
 }
 
 } // namespace JSC
diff --git a/runtime/RopeImpl.cpp b/runtime/RopeImpl.cpp
new file mode 100644 (file)
index 0000000..25b9848
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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 "RopeImpl.h"
+
+namespace JSC {
+
+void RopeImpl::derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue)
+{
+    unsigned fiberCount = this->fiberCount();
+    for (unsigned i = 0; i < fiberCount; ++i) {
+        Fiber& fiber = m_fibers[i];
+        if (isRope(fiber)) {
+            RopeImpl* nextRope = static_cast<RopeImpl*>(fiber);
+            if (nextRope->hasOneRef())
+                workQueue.append(nextRope);
+            else
+                nextRope->deref();
+        } else
+            static_cast<UStringImpl*>(fiber)->deref();
+    }
+}
+
+void RopeImpl::destructNonRecursive()
+{
+    Vector<RopeImpl*, 32> workQueue;
+
+    derefFibersNonRecursive(workQueue);
+    delete this;
+
+    while (!workQueue.isEmpty()) {
+        RopeImpl* rope = workQueue.last();
+        workQueue.removeLast();
+        rope->derefFibersNonRecursive(workQueue);
+        delete rope;
+    }
+}
+
+} // namespace JSC
diff --git a/runtime/RopeImpl.h b/runtime/RopeImpl.h
new file mode 100644 (file)
index 0000000..ac2b502
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2009, 2010 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 RopeImpl_h
+#define RopeImpl_h
+
+#include "UStringImpl.h"
+
+namespace JSC {
+
+class RopeImpl : public StringImplBase {
+public:
+    // A RopeImpl is composed from a set of smaller strings called Fibers.
+    // Each Fiber in a rope is either UStringImpl or another RopeImpl.
+    typedef StringImplBase* Fiber;
+
+    // Creates a RopeImpl comprising of 'fiberCount' Fibers.
+    // The RopeImpl is constructed in an uninitialized state - initialize must be called for each Fiber in the RopeImpl.
+    static PassRefPtr<RopeImpl> tryCreateUninitialized(unsigned fiberCount)
+    {
+        void* allocation;
+        if (tryFastMalloc(sizeof(RopeImpl) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation))
+            return adoptRef(new (allocation) RopeImpl(fiberCount));
+        return 0;
+    }
+
+    static bool isRope(Fiber fiber)
+    {
+        return !fiber->isStringImpl();
+    }
+
+    static void deref(Fiber fiber)
+    {
+        if (isRope(fiber))
+            static_cast<RopeImpl*>(fiber)->deref();
+        else
+            static_cast<UStringImpl*>(fiber)->deref();
+    }
+
+    void initializeFiber(unsigned &index, Fiber fiber)
+    {
+        m_fibers[index++] = fiber;
+        fiber->ref();
+        m_length += fiber->length();
+    }
+
+    unsigned fiberCount() { return m_size; }
+    Fiber* fibers() { return m_fibers; }
+
+    ALWAYS_INLINE void deref()
+    {
+        m_refCountAndFlags -= s_refCountIncrement;
+        if (!(m_refCountAndFlags & s_refCountMask))
+            destructNonRecursive();
+    }
+
+private:
+    RopeImpl(unsigned fiberCount)
+        : StringImplBase(ConstructNonStringImpl)
+        , m_size(fiberCount)
+    {
+    }
+
+    void destructNonRecursive();
+    void derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue);
+
+    bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; }
+
+    unsigned m_size;
+    Fiber m_fibers[1];
+};
+
+}
+
+#endif
index 78bd4e42c4f7b4290695a23dbe11bdd5285b674e..0f5df4a23884bfe40f651fc335dda7a1f13ecfeb 100644 (file)
@@ -43,10 +43,10 @@ class SmallStringsStorage : public Noncopyable {
 public:
     SmallStringsStorage();
 
 public:
     SmallStringsStorage();
 
-    UString::Rep* rep(unsigned char character) { return &m_reps[character]; }
+    UString::Rep* rep(unsigned char character) { return m_reps[character].get(); }
 
 private:
 
 private:
-    UString::Rep m_reps[numCharactersToStore];
+    RefPtr<UString::Rep> m_reps[numCharactersToStore];
 };
 
 SmallStringsStorage::SmallStringsStorage()
 };
 
 SmallStringsStorage::SmallStringsStorage()
@@ -55,7 +55,7 @@ SmallStringsStorage::SmallStringsStorage()
     RefPtr<UStringImpl> baseString = UStringImpl::createUninitialized(numCharactersToStore, characterBuffer);
     for (unsigned i = 0; i < numCharactersToStore; ++i) {
         characterBuffer[i] = i;
     RefPtr<UStringImpl> baseString = UStringImpl::createUninitialized(numCharactersToStore, characterBuffer);
     for (unsigned i = 0; i < numCharactersToStore; ++i) {
         characterBuffer[i] = i;
-        new (&m_reps[i]) UString::Rep(&characterBuffer[i], 1, PassRefPtr<UStringImpl>(baseString));
+        m_reps[i] = UStringImpl::create(baseString, i, 1);
     }
 }
 
     }
 }
 
index cc11d0ace5c1e56ccf885304d2ccdcd4843f8f97..bc337c995806d35c1af111c5693760de122d3d54 100644 (file)
@@ -60,7 +60,9 @@ namespace JSC {
         void clear();
 
         unsigned count() const;
         void clear();
 
         unsigned count() const;
-
+#if ENABLE(JIT)
+        JSString** singleCharacterStrings() { return m_singleCharacterStrings; }
+#endif
     private:
         void createEmptyString(JSGlobalData*);
         void createSingleCharacterString(JSGlobalData*, unsigned char);
     private:
         void createEmptyString(JSGlobalData*);
         void createSingleCharacterString(JSGlobalData*, unsigned char);
index 8e18d3785a0feb54d7ea017c68d578fa62fa2ae9..f028c086e298145de5daeb76d680f04998db0d64 100644 (file)
@@ -39,12 +39,12 @@ public:
 
     void append(const char* str)
     {
 
     void append(const char* str)
     {
-        buffer.append(str, strlen(str));
+        append(str, strlen(str));
     }
 
     void append(const char* str, size_t len)
     {
     }
 
     void append(const char* str, size_t len)
     {
-        buffer.reserveCapacity(buffer.size() + len);
+        reserveCapacity(buffer.size() + len);
         for (size_t i = 0; i < len; i++)
             buffer.append(static_cast<unsigned char>(str[i]));
     }
         for (size_t i = 0; i < len; i++)
             buffer.append(static_cast<unsigned char>(str[i]));
     }
@@ -60,19 +60,25 @@ public:
     }
 
     bool isEmpty() { return buffer.isEmpty(); }
     }
 
     bool isEmpty() { return buffer.isEmpty(); }
-    void reserveCapacity(size_t newCapacity) { buffer.reserveCapacity(newCapacity); }
+    void reserveCapacity(size_t newCapacity)
+    {
+        if (newCapacity < buffer.capacity())
+            return;
+        buffer.reserveCapacity(std::max(newCapacity, buffer.capacity() + buffer.capacity() / 4 + 1));
+    }
     void resize(size_t size) { buffer.resize(size); }
     size_t size() const { return buffer.size(); }
 
     UChar operator[](size_t i) const { return buffer.at(i); }
 
     void resize(size_t size) { buffer.resize(size); }
     size_t size() const { return buffer.size(); }
 
     UChar operator[](size_t i) const { return buffer.at(i); }
 
-    UString release()
+    UString build()
     {
         buffer.shrinkToFit();
     {
         buffer.shrinkToFit();
+        ASSERT(buffer.data() || !buffer.size());
         return UString::adopt(buffer);
     }
 
         return UString::adopt(buffer);
     }
 
-private:
+protected:
     Vector<UChar, 64> buffer;
 };
 
     Vector<UChar, 64> buffer;
 };
 
index c7b62bfc81a05f77346a2211b1d9bef8bb989614..94bee4391d1a0996f2a5d4c5aa641d9c29092e7a 100644 (file)
@@ -54,8 +54,11 @@ StringConstructor::StringConstructor(ExecState* exec, NonNullPassRefPtr<Structur
     putDirectWithoutTransition(exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
 
     // ECMA 15.5.3.2 fromCharCode()
     putDirectWithoutTransition(exec->propertyNames().prototype, stringPrototype, ReadOnly | DontEnum | DontDelete);
 
     // ECMA 15.5.3.2 fromCharCode()
+#if ENABLE(JIT) && ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
+    putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, exec->globalData().getThunk(fromCharCodeThunkGenerator), stringFromCharCode), DontEnum);
+#else
     putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
     putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().fromCharCode, stringFromCharCode), DontEnum);
-
+#endif
     // no. of arguments for constructor
     putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
 }
     // no. of arguments for constructor
     putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly | DontEnum | DontDelete);
 }
index d002e071a331f55f7b69abad26ee5697dedc73de..cd1cc89219a057f196d20619208b5626799e73e8 100644 (file)
 #include "JSGlobalObjectFunctions.h"
 #include "JSArray.h"
 #include "JSFunction.h"
 #include "JSGlobalObjectFunctions.h"
 #include "JSArray.h"
 #include "JSFunction.h"
+#include "JSStringBuilder.h"
+#include "Lookup.h"
 #include "ObjectPrototype.h"
 #include "Operations.h"
 #include "PropertyNameArray.h"
 #include "ObjectPrototype.h"
 #include "Operations.h"
 #include "PropertyNameArray.h"
+#include "RegExpCache.h"
 #include "RegExpConstructor.h"
 #include "RegExpObject.h"
 #include <wtf/ASCIICType.h>
 #include "RegExpConstructor.h"
 #include "RegExpObject.h"
 #include <wtf/ASCIICType.h>
@@ -149,7 +152,7 @@ bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier
 
 // ------------------------------ Functions --------------------------
 
 
 // ------------------------------ Functions --------------------------
 
-static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, int i)
+static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, unsigned i)
 {
     Vector<UChar> substitutedReplacement;
     int offset = 0;
 {
     Vector<UChar> substitutedReplacement;
     int offset = 0;
@@ -205,7 +208,7 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
         i += 1 + advance;
         offset = i + 1;
         substitutedReplacement.append(source.data() + backrefStart, backrefLength);
         i += 1 + advance;
         offset = i + 1;
         substitutedReplacement.append(source.data() + backrefStart, backrefLength);
-    } while ((i = replacement.find('$', i + 1)) != -1);
+    } while ((i = replacement.find('$', i + 1)) != UString::NotFound);
 
     if (replacement.size() - offset)
         substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset);
 
     if (replacement.size() - offset)
         substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset);
@@ -216,8 +219,8 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
 
 static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
 {
 
 static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
 {
-    int i = replacement.find('$', 0);
-    if (UNLIKELY(i != -1))
+    unsigned i = replacement.find('$', 0);
+    if (UNLIKELY(i != UString::NotFound))
         return substituteBackreferencesSlow(replacement, source, ovector, reg, i);
     return replacement;
 }
         return substituteBackreferencesSlow(replacement, source, ovector, reg, i);
     return replacement;
 }
@@ -227,14 +230,71 @@ 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());
 }
 
     return Collator::userDefault()->collate(reinterpret_cast<const ::UChar*>(a.data()), a.size(), reinterpret_cast<const ::UChar*>(b.data()), b.size());
 }
 
+struct StringRange {
+public:
+    StringRange(int pos, int len)
+        : position(pos)
+        , length(len)
+    {
+    }
+
+    StringRange()
+    {
+    }
+
+    int position;
+    int length;
+};
+
+JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount, const UString* separators, int separatorCount);
+JSValue jsSpliceSubstringsWithSeparators(ExecState* exec, JSString* sourceVal, const UString& source, const StringRange* substringRanges, int rangeCount, const UString* separators, int separatorCount)
+{
+    if (rangeCount == 1 && separatorCount == 0) {
+        int sourceSize = source.size();
+        int position = substringRanges[0].position;
+        int length = substringRanges[0].length;
+        if (position <= 0 && length >= sourceSize)
+            return sourceVal;
+        // We could call UString::substr, but this would result in redundant checks
+        return jsString(exec, UStringImpl::create(source.rep(), max(0, position), min(sourceSize, length)));
+    }
+
+    int totalLength = 0;
+    for (int i = 0; i < rangeCount; i++)
+        totalLength += substringRanges[i].length;
+    for (int i = 0; i < separatorCount; i++)
+        totalLength += separators[i].size();
+
+    if (totalLength == 0)
+        return jsString(exec, "");
+
+    UChar* buffer;
+    PassRefPtr<UStringImpl> impl = UStringImpl::tryCreateUninitialized(totalLength, buffer);
+    if (!impl)
+        return throwOutOfMemoryError(exec);
+
+    int maxCount = max(rangeCount, separatorCount);
+    int bufferPos = 0;
+    for (int i = 0; i < maxCount; i++) {
+        if (i < rangeCount) {
+            UStringImpl::copyChars(buffer + bufferPos, source.data() + substringRanges[i].position, substringRanges[i].length);
+            bufferPos += substringRanges[i].length;
+        }
+        if (i < separatorCount) {
+            UStringImpl::copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());
+            bufferPos += separators[i].size();
+        }
+    }
+
+    return jsString(exec, impl);
+}
+
 JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSString* sourceVal = thisValue.toThisJSString(exec);
 JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     JSString* sourceVal = thisValue.toThisJSString(exec);
-    const UString& source = sourceVal->value(exec);
-
     JSValue pattern = args.at(0);
     JSValue pattern = args.at(0);
-
     JSValue replacement = args.at(1);
     JSValue replacement = args.at(1);
+
     UString replacementString;
     CallData callData;
     CallType callType = replacement.getCallData(callData);
     UString replacementString;
     CallData callData;
     CallType callType = replacement.getCallData(callData);
@@ -242,15 +302,18 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
         replacementString = replacement.toString(exec);
 
     if (pattern.inherits(&RegExpObject::info)) {
         replacementString = replacement.toString(exec);
 
     if (pattern.inherits(&RegExpObject::info)) {
+        const UString& source = sourceVal->value(exec);
+        if (exec->hadException())
+            return JSValue();
         RegExp* reg = asRegExpObject(pattern)->regExp();
         bool global = reg->global();
 
         RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
 
         int lastIndex = 0;
         RegExp* reg = asRegExpObject(pattern)->regExp();
         bool global = reg->global();
 
         RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
 
         int lastIndex = 0;
-        int startPosition = 0;
+        unsigned startPosition = 0;
 
 
-        Vector<UString::Range, 16> sourceRanges;
+        Vector<StringRange, 16> sourceRanges;
         Vector<UString, 16> replacements;
 
         // This is either a loop (if global is set) or a one-way (if not).
         Vector<UString, 16> replacements;
 
         // This is either a loop (if global is set) or a one-way (if not).
@@ -269,7 +332,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
                 if (matchIndex < 0)
                     break;
                 
                 if (matchIndex < 0)
                     break;
                 
-                sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+                sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
 
                 int completeMatchStart = ovector[0];
                 unsigned i = 0;
 
                 int completeMatchStart = ovector[0];
                 unsigned i = 0;
@@ -311,7 +374,7 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
                 if (matchIndex < 0)
                     break;
 
                 if (matchIndex < 0)
                     break;
 
-                sourceRanges.append(UString::Range(lastIndex, matchIndex - lastIndex));
+                sourceRanges.append(StringRange(lastIndex, matchIndex - lastIndex));
 
                 if (callType != CallTypeNone) {
                     int completeMatchStart = ovector[0];
 
                 if (callType != CallTypeNone) {
                     int completeMatchStart = ovector[0];
@@ -351,19 +414,22 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
         if (!lastIndex && replacements.isEmpty())
             return sourceVal;
 
         if (!lastIndex && replacements.isEmpty())
             return sourceVal;
 
-        if (lastIndex < source.size())
-            sourceRanges.append(UString::Range(lastIndex, source.size() - lastIndex));
+        if (static_cast<unsigned>(lastIndex) < source.size())
+            sourceRanges.append(StringRange(lastIndex, source.size() - lastIndex));
 
 
-        return jsString(exec, source.spliceSubstringsWithSeparators(sourceRanges.data(), sourceRanges.size(),
-            replacements.data(), replacements.size()));
+        return jsSpliceSubstringsWithSeparators(exec, sourceVal, source, sourceRanges.data(), sourceRanges.size(), replacements.data(), replacements.size());
     }
 
     // Not a regular expression, so treat the pattern as a string.
 
     UString patternString = pattern.toString(exec);
     }
 
     // Not a regular expression, so treat the pattern as a string.
 
     UString patternString = pattern.toString(exec);
-    int matchPos = source.find(patternString);
+    if (patternString.size() == 1 && callType == CallTypeNone)
+        return sourceVal->replaceCharacter(exec, patternString[0], replacementString);
+    
+    const UString& source = sourceVal->value(exec);
+    unsigned matchPos = source.find(patternString);
 
 
-    if (matchPos == -1)
+    if (matchPos == UString::NotFound)
         return sourceVal;
 
     int matchLen = patternString.size();
         return sourceVal;
 
     int matchLen = patternString.size();
@@ -375,9 +441,10 @@ JSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec, JSObject*, JSValue
 
         replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec);
     }
 
         replacementString = call(exec, replacement, callType, callData, exec->globalThisValue(), args).toString(exec);
     }
-
-    int ovector[2] = { matchPos, matchPos + matchLen };
-    return jsString(exec, source.replaceRange(matchPos, matchLen, substituteBackreferences(replacementString, source, ovector, 0)));
+    
+    size_t matchEnd = matchPos + matchLen;
+    int ovector[2] = { matchPos, matchEnd };
+    return jsString(exec, source.substr(0, matchPos), substituteBackreferences(replacementString, source, ovector, 0), source.substr(matchEnd));
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
@@ -461,7 +528,10 @@ JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue
         pos = static_cast<int>(dpos);
     }
 
         pos = static_cast<int>(dpos);
     }
 
-    return jsNumber(exec, s.find(u2, pos));
+    unsigned result = s.find(u2, pos);
+    if (result == UString::NotFound)
+        return jsNumber(exec, -1);
+    return jsNumber(exec, result);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -483,7 +553,11 @@ JSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec, JSObject*, JSV
     else if (isnan(dpos))
         dpos = len;
 #endif
     else if (isnan(dpos))
         dpos = len;
 #endif
-    return jsNumber(exec, s.rfind(u2, static_cast<int>(dpos)));
+
+    unsigned result = s.rfind(u2, static_cast<unsigned>(dpos));
+    if (result == UString::NotFound)
+        return jsNumber(exec, -1);
+    return jsNumber(exec, result);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -503,7 +577,7 @@ JSValue JSC_HOST_CALL stringProtoFuncMatch(ExecState* exec, JSObject*, JSValue t
          *  If regexp is not an object whose [[Class]] property is "RegExp", it is
          *  replaced with the result of the expression new RegExp(regexp).
          */
          *  If regexp is not an object whose [[Class]] property is "RegExp", it is
          *  replaced with the result of the expression new RegExp(regexp).
          */
-        reg = RegExp::create(&exec->globalData(), a0.toString(exec));
+        reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString::null());
     }
     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
     int pos;
     }
     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
     int pos;
@@ -553,7 +627,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSearch(ExecState* exec, JSObject*, JSValue
          *  If regexp is not an object whose [[Class]] property is "RegExp", it is
          *  replaced with the result of the expression new RegExp(regexp).
          */
          *  If regexp is not an object whose [[Class]] property is "RegExp", it is
          *  replaced with the result of the expression new RegExp(regexp).
          */
-        reg = RegExp::create(&exec->globalData(), a0.toString(exec));
+        reg = exec->globalData().regExpCache()->lookupOrCreate(a0.toString(exec), UString::null());
     }
     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
     int pos;
     }
     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
     int pos;
@@ -595,7 +669,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue t
 
     JSArray* result = constructEmptyArray(exec);
     unsigned i = 0;
 
     JSArray* result = constructEmptyArray(exec);
     unsigned i = 0;
-    int p0 = 0;
+    unsigned p0 = 0;
     unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec);
     if (a0.inherits(&RegExpObject::info)) {
         RegExp* reg = asRegExpObject(a0)->regExp();
     unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec);
     if (a0.inherits(&RegExpObject::info)) {
         RegExp* reg = asRegExpObject(a0)->regExp();
@@ -603,7 +677,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue t
             // empty string matched by regexp -> empty array
             return result;
         }
             // empty string matched by regexp -> empty array
             return result;
         }
-        int pos = 0;
+        unsigned pos = 0;
         while (i != limit && pos < s.size()) {
             Vector<int, 32> ovector;
             int mpos = reg->match(s, pos, &ovector);
         while (i != limit && pos < s.size()) {
             Vector<int, 32> ovector;
             int mpos = reg->match(s, pos, &ovector);
@@ -611,7 +685,7 @@ JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue t
                 break;
             int mlen = ovector[1] - ovector[0];
             pos = mpos + (mlen == 0 ? 1 : mlen);
                 break;
             int mlen = ovector[1] - ovector[0];
             pos = mpos + (mlen == 0 ? 1 : mlen);
-            if (mpos != p0 || mlen) {
+            if (static_cast<unsigned>(mpos) != p0 || mlen) {
                 result->put(exec, i++, jsSubstring(exec, s, p0, mpos - p0));
                 p0 = mpos + mlen;
             }
                 result->put(exec, i++, jsSubstring(exec, s, p0, mpos - p0));
                 p0 = mpos + mlen;
             }
@@ -633,8 +707,9 @@ JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue t
             while (i != limit && p0 < s.size() - 1)
                 result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++));
         } else {
             while (i != limit && p0 < s.size() - 1)
                 result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++));
         } else {
-            int pos;
-            while (i != limit && (pos = s.find(u2, p0)) >= 0) {
+            unsigned pos;
+            
+            while (i != limit && (pos = s.find(u2, p0)) != UString::NotFound) {
                 result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0));
                 p0 = pos + u2.size();
             }
                 result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0));
                 p0 = pos + u2.size();
             }
@@ -789,62 +864,62 @@ JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, J
 JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, makeString("<big>", s, "</big>"));
+    return jsMakeNontrivialString(exec, "<big>", s, "</big>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, makeString("<small>", s, "</small>"));
+    return jsMakeNontrivialString(exec, "<small>", s, "</small>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, makeString("<blink>", s, "</blink>"));
+    return jsMakeNontrivialString(exec, "<blink>", s, "</blink>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, makeString("<b>", s, "</b>"));
+    return jsMakeNontrivialString(exec, "<b>", s, "</b>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsString(exec, makeString("<tt>", s, "</tt>"));
+    return jsMakeNontrivialString(exec, "<tt>", s, "</tt>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, makeString("<i>", s, "</i>"));
+    return jsMakeNontrivialString(exec, "<i>", s, "</i>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, makeString("<strike>", s, "</strike>"));
+    return jsMakeNontrivialString(exec, "<strike>", s, "</strike>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, makeString("<sub>", s, "</sub>"));
+    return jsMakeNontrivialString(exec, "<sub>", s, "</sub>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
 {
     UString s = thisValue.toThisString(exec);
-    return jsNontrivialString(exec, makeString("<sup>", s, "</sup>"));
+    return jsMakeNontrivialString(exec, "<sup>", s, "</sup>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     JSValue a0 = args.at(0);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     JSValue a0 = args.at(0);
-    return jsNontrivialString(exec, makeString("<font color=\"", a0.toString(exec), "\">", s, "</font>"));
+    return jsMakeNontrivialString(exec, "<font color=\"", a0.toString(exec), "\">", s, "</font>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -886,14 +961,14 @@ JSValue JSC_HOST_CALL stringProtoFuncFontsize(ExecState* exec, JSObject*, JSValu
         return jsNontrivialString(exec, impl);
     }
 
         return jsNontrivialString(exec, impl);
     }
 
-    return jsNontrivialString(exec, makeString("<font size=\"", a0.toString(exec), "\">", s, "</font>"));
+    return jsMakeNontrivialString(exec, "<font size=\"", a0.toString(exec), "\">", s, "</font>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     JSValue a0 = args.at(0);
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncAnchor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 {
     UString s = thisValue.toThisString(exec);
     JSValue a0 = args.at(0);
-    return jsNontrivialString(exec, makeString("<a name=\"", a0.toString(exec), "\">", s, "</a>"));
+    return jsMakeNontrivialString(exec, "<a name=\"", a0.toString(exec), "\">", s, "</a>");
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
 }
 
 JSValue JSC_HOST_CALL stringProtoFuncLink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
@@ -942,12 +1017,12 @@ static inline bool isTrimWhitespace(UChar c)
 static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKind)
 {
     UString str = thisValue.toThisString(exec);
 static inline JSValue trimString(ExecState* exec, JSValue thisValue, int trimKind)
 {
     UString str = thisValue.toThisString(exec);
-    int left = 0;
+    unsigned left = 0;
     if (trimKind & TrimLeft) {
         while (left < str.size() && isTrimWhitespace(str[left]))
             left++;
     }
     if (trimKind & TrimLeft) {
         while (left < str.size() && isTrimWhitespace(str[left]))
             left++;
     }
-    int right = str.size();
+    unsigned right = str.size();
     if (trimKind & TrimRight) {
         while (right > left && isTrimWhitespace(str[right - 1]))
             right--;
     if (trimKind & TrimRight) {
         while (right > left && isTrimWhitespace(str[right - 1]))
             right--;
index 546e2bf6e8cfc35d43b7d3072f3a413cc224fc8f..6d13f4b98af3d42ae06c24e28633c066085e6427 100644 (file)
@@ -79,6 +79,106 @@ static HashSet<Structure*>& liveStructureSet = *(new HashSet<Structure*>);
 
 static int comparePropertyMapEntryIndices(const void* a, const void* b);
 
 
 static int comparePropertyMapEntryIndices(const void* a, const void* b);
 
+inline void Structure::setTransitionTable(TransitionTable* table)
+{
+    ASSERT(m_isUsingSingleSlot);
+#ifndef NDEBUG
+    setSingleTransition(0);
+#endif
+    m_isUsingSingleSlot = false;
+    m_transitions.m_table = table;
+    // This implicitly clears the flag that indicates we're using a single transition
+    ASSERT(!m_isUsingSingleSlot);
+}
+
+// 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 Structure::transitionTableContains(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
+{
+    if (m_isUsingSingleSlot) {
+        Structure* existingTransition = singleTransition();
+        return existingTransition && existingTransition->m_nameInPrevious.get() == key.first
+               && existingTransition->m_attributesInPrevious == key.second
+               && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0);
+    }
+    TransitionTable::iterator find = transitionTable()->find(key);
+    if (find == transitionTable()->end())
+        return false;
+
+    return find->second.first || find->second.second->transitionedFor(specificValue);
+}
+
+inline Structure* Structure::transitionTableGet(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const
+{
+    if (m_isUsingSingleSlot) {
+        Structure* existingTransition = singleTransition();
+        if (existingTransition && existingTransition->m_nameInPrevious.get() == key.first
+            && existingTransition->m_attributesInPrevious == key.second
+            && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0))
+            return existingTransition;
+        return 0;
+    }
+
+    Transition transition = transitionTable()->get(key);
+    if (transition.second && transition.second->transitionedFor(specificValue))
+        return transition.second;
+    return transition.first;
+}
+
+inline bool Structure::transitionTableHasTransition(const StructureTransitionTableHash::Key& key) const
+{
+    if (m_isUsingSingleSlot) {
+        Structure* transition = singleTransition();
+        return transition && transition->m_nameInPrevious == key.first
+        && transition->m_attributesInPrevious == key.second;
+    }
+    return transitionTable()->contains(key);
+}
+
+inline void Structure::transitionTableRemove(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
+{
+    if (m_isUsingSingleSlot) {
+        ASSERT(transitionTableContains(key, specificValue));
+        setSingleTransition(0);
+        return;
+    }
+    TransitionTable::iterator find = transitionTable()->find(key);
+    if (!specificValue)
+        find->second.first = 0;
+    else
+        find->second.second = 0;
+    if (!find->second.first && !find->second.second)
+        transitionTable()->remove(find);
+}
+
+inline void Structure::transitionTableAdd(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue)
+{
+    if (m_isUsingSingleSlot) {
+        if (!singleTransition()) {
+            setSingleTransition(structure);
+            return;
+        }
+        Structure* existingTransition = singleTransition();
+        TransitionTable* transitionTable = new TransitionTable;
+        setTransitionTable(transitionTable);
+        if (existingTransition)
+            transitionTableAdd(std::make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious);
+    }
+    if (!specificValue) {
+        TransitionTable::iterator find = transitionTable()->find(key);
+        if (find == transitionTable()->end())
+            transitionTable()->add(key, Transition(structure, static_cast<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(!transitionTable()->contains(key));
+        transitionTable()->add(key, Transition(static_cast<Structure*>(0), structure));
+    }
+}
+
 void Structure::dumpStatistics()
 {
 #if DUMP_STRUCTURE_ID_STATISTICS
 void Structure::dumpStatistics()
 {
 #if DUMP_STRUCTURE_ID_STATISTICS
@@ -136,7 +236,10 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo, unsigned anony
     , m_attributesInPrevious(0)
     , m_specificFunctionThrashCount(0)
     , m_anonymousSlotCount(anonymousSlotCount)
     , m_attributesInPrevious(0)
     , m_specificFunctionThrashCount(0)
     , m_anonymousSlotCount(anonymousSlotCount)
+    , m_isUsingSingleSlot(true)
 {
 {
+    m_transitions.m_singleTransition = 0;
+
     ASSERT(m_prototype);
     ASSERT(m_prototype.isObject() || m_prototype.isNull());
 
     ASSERT(m_prototype);
     ASSERT(m_prototype.isObject() || m_prototype.isNull());
 
@@ -159,12 +262,10 @@ Structure::~Structure()
 {
     if (m_previous) {
         ASSERT(m_nameInPrevious);
 {
     if (m_previous) {
         ASSERT(m_nameInPrevious);
-        m_previous->table.remove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious);
+        m_previous->transitionTableRemove(make_pair(m_nameInPrevious.get(), m_attributesInPrevious), m_specificValueInPrevious);
 
     }
 
     }
-    
-    if (m_enumerationCache)
-        m_enumerationCache->setCachedStructure(0);
+    ASSERT(!m_enumerationCache.hasDeadObject());
 
     if (m_propertyTable) {
         unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
 
     if (m_propertyTable) {
         unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
@@ -177,6 +278,9 @@ Structure::~Structure()
         fastFree(m_propertyTable);
     }
 
         fastFree(m_propertyTable);
     }
 
+    if (!m_isUsingSingleSlot)
+        delete transitionTable();
+
 #ifndef NDEBUG
 #if ENABLE(JSC_MULTIPLE_THREADS)
     MutexLocker protect(ignoreSetMutex);
 #ifndef NDEBUG
 #if ENABLE(JSC_MULTIPLE_THREADS)
     MutexLocker protect(ignoreSetMutex);
@@ -340,7 +444,7 @@ PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Struct
     ASSERT(!structure->isDictionary());
     ASSERT(structure->typeInfo().type() == ObjectType);
 
     ASSERT(!structure->isDictionary());
     ASSERT(structure->typeInfo().type() == ObjectType);
 
-    if (Structure* existingTransition = structure->table.get(make_pair(propertyName.ustring().rep(), attributes), specificValue)) {
+    if (Structure* existingTransition = structure->transitionTableGet(make_pair(propertyName.ustring().rep(), attributes), specificValue)) {
         ASSERT(existingTransition->m_offset != noOffset);
         offset = existingTransition->m_offset + existingTransition->m_anonymousSlotCount;
         ASSERT(offset >= structure->m_anonymousSlotCount);
         ASSERT(existingTransition->m_offset != noOffset);
         offset = existingTransition->m_offset + existingTransition->m_anonymousSlotCount;
         ASSERT(offset >= structure->m_anonymousSlotCount);
@@ -405,7 +509,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
 
     transition->m_offset = offset - structure->m_anonymousSlotCount;
     ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount());
 
     transition->m_offset = offset - structure->m_anonymousSlotCount;
     ASSERT(structure->anonymousSlotCount() == transition->anonymousSlotCount());
-    structure->table.add(make_pair(propertyName.ustring().rep(), attributes), transition.get(), specificValue);
+    structure->transitionTableAdd(make_pair(propertyName.ustring().rep(), attributes), transition.get(), specificValue);
     return transition.release();
 }
 
     return transition.release();
 }
 
@@ -852,7 +956,7 @@ size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCel
 
 bool Structure::hasTransition(UString::Rep* rep, unsigned attributes)
 {
 
 bool Structure::hasTransition(UString::Rep* rep, unsigned attributes)
 {
-    return table.hasTransition(make_pair(rep, attributes));
+    return transitionTableHasTransition(make_pair(rep, attributes));
 }
 
 size_t Structure::remove(const Identifier& propertyName)
 }
 
 size_t Structure::remove(const Identifier& propertyName)
index 451ba3cefe3f5c030ed4e6a01a6e0838d699966e..968443a828d1b2e8e7f2e58465f5109e5afe84d9 100644 (file)
@@ -102,7 +102,7 @@ namespace JSC {
 
         void growPropertyStorageCapacity();
         unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; }
 
         void growPropertyStorageCapacity();
         unsigned propertyStorageCapacity() const { return m_propertyStorageCapacity; }
-        unsigned propertyStorageSize() const { return m_anonymousSlotCount + (m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : m_offset + 1); }
+        unsigned propertyStorageSize() const { return m_anonymousSlotCount + (m_propertyTable ? m_propertyTable->keyCount + (m_propertyTable->deletedOffsets ? m_propertyTable->deletedOffsets->size() : 0) : static_cast<unsigned>(m_offset + 1)); }
         bool isUsingInlineStorage() const;
 
         size_t get(const Identifier& propertyName);
         bool isUsingInlineStorage() const;
 
         size_t get(const Identifier& propertyName);
@@ -179,6 +179,20 @@ namespace JSC {
             // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
             return m_offset == noOffset ? 0 : m_offset + 1;
         }
             // Since the number of transitions is always the same as m_offset, we keep the size of Structure down by not storing both.
             return m_offset == noOffset ? 0 : m_offset + 1;
         }
+
+        typedef std::pair<Structure*, Structure*> Transition;
+        typedef HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> TransitionTable;
+
+        inline bool transitionTableContains(const StructureTransitionTableHash::Key& key, JSCell* specificValue);
+        inline void transitionTableRemove(const StructureTransitionTableHash::Key& key, JSCell* specificValue);
+        inline void transitionTableAdd(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue);
+        inline bool transitionTableHasTransition(const StructureTransitionTableHash::Key& key) const;
+        inline Structure* transitionTableGet(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const;
+
+        TransitionTable* transitionTable() const { ASSERT(!m_isUsingSingleSlot); return m_transitions.m_table; }
+        inline void setTransitionTable(TransitionTable* table);
+        Structure* singleTransition() const { ASSERT(m_isUsingSingleSlot); return m_transitions.m_singleTransition; }
+        void setSingleTransition(Structure* structure) { ASSERT(m_isUsingSingleSlot); m_transitions.m_singleTransition = structure; }
         
         bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
 
         
         bool isValid(ExecState*, StructureChain* cachedPrototypeChain) const;
 
@@ -199,7 +213,11 @@ namespace JSC {
         RefPtr<UString::Rep> m_nameInPrevious;
         JSCell* m_specificValueInPrevious;
 
         RefPtr<UString::Rep> m_nameInPrevious;
         JSCell* m_specificValueInPrevious;
 
-        StructureTransitionTable table;
+        // 'm_isUsingSingleSlot' indicates whether we are using the single transition optimisation.
+        union {
+            TransitionTable* m_table;
+            Structure* m_singleTransition;
+        } m_transitions;
 
         WeakGCPtr<JSPropertyNameIterator> m_enumerationCache;
 
 
         WeakGCPtr<JSPropertyNameIterator> m_enumerationCache;
 
@@ -224,7 +242,8 @@ namespace JSC {
 #endif
         unsigned m_specificFunctionThrashCount : 2;
         unsigned m_anonymousSlotCount : 5;
 #endif
         unsigned m_specificFunctionThrashCount : 2;
         unsigned m_anonymousSlotCount : 5;
-        // 5 free bits
+        unsigned m_isUsingSingleSlot : 1;
+        // 4 free bits
     };
 
     inline size_t Structure::get(const Identifier& propertyName)
     };
 
     inline size_t Structure::get(const Identifier& propertyName)
@@ -271,58 +290,7 @@ namespace JSC {
                 return m_propertyTable->entries()[entryIndex - 1].offset;
         }
     }
                 return m_propertyTable->entries()[entryIndex - 1].offset;
         }
     }
-    
-    bool StructureTransitionTable::contains(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
-    {
-        if (usingSingleTransitionSlot()) {
-            Structure* existingTransition = singleTransition();
-            return existingTransition && existingTransition->m_nameInPrevious.get() == key.first
-                   && existingTransition->m_attributesInPrevious == key.second
-                   && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0);
-        }
-        TransitionTable::iterator find = table()->find(key);
-        if (find == table()->end())
-            return false;
-
-        return find->second.first || find->second.second->transitionedFor(specificValue);
-    }
 
 
-    Structure* StructureTransitionTable::get(const StructureTransitionTableHash::Key& key, JSCell* specificValue) const
-    {
-        if (usingSingleTransitionSlot()) {
-            Structure* existingTransition = singleTransition();
-            if (existingTransition && existingTransition->m_nameInPrevious.get() == key.first
-                && existingTransition->m_attributesInPrevious == key.second
-                && (existingTransition->m_specificValueInPrevious == specificValue || existingTransition->m_specificValueInPrevious == 0))
-                return existingTransition;
-            return 0;
-        }
-
-        Transition transition = table()->get(key);
-        if (transition.second && transition.second->transitionedFor(specificValue))
-            return transition.second;
-        return transition.first;
-    }
-
-    bool StructureTransitionTable::hasTransition(const StructureTransitionTableHash::Key& key) const
-    {
-        if (usingSingleTransitionSlot()) {
-            Structure* transition = singleTransition();
-            return transition && transition->m_nameInPrevious == key.first
-            && transition->m_attributesInPrevious == key.second;
-        }
-        return table()->contains(key);
-    }
-    
-    void StructureTransitionTable::reifySingleTransition()
-    {
-        ASSERT(usingSingleTransitionSlot());
-        Structure* existingTransition = singleTransition();
-        TransitionTable* transitionTable = new TransitionTable;
-        setTransitionTable(transitionTable);
-        if (existingTransition)
-            add(std::make_pair(existingTransition->m_nameInPrevious.get(), existingTransition->m_attributesInPrevious), existingTransition, existingTransition->m_specificValueInPrevious);
-    }
 } // namespace JSC
 
 #endif // Structure_h
 } // namespace JSC
 
 #endif // Structure_h
index 320dbddc9a41eb627c60ccde75459ecd086df777..d1dc2d9c645499c9981203f5f8528b38265a6552 100644 (file)
@@ -30,7 +30,6 @@
 #include <wtf/HashFunctions.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashTraits.h>
 #include <wtf/HashFunctions.h>
 #include <wtf/HashMap.h>
 #include <wtf/HashTraits.h>
-#include <wtf/PtrAndFlags.h>
 #include <wtf/OwnPtr.h>
 #include <wtf/RefPtr.h>
 
 #include <wtf/OwnPtr.h>
 #include <wtf/RefPtr.h>
 
@@ -67,99 +66,6 @@ namespace JSC {
         static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
     };
 
         static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); }
     };
 
-    class StructureTransitionTable {
-        typedef std::pair<Structure*, Structure*> Transition;
-        typedef HashMap<StructureTransitionTableHash::Key, Transition, StructureTransitionTableHash, StructureTransitionTableHashTraits> TransitionTable;
-    public:
-        StructureTransitionTable() {
-            m_transitions.m_singleTransition.set(0);
-            m_transitions.m_singleTransition.setFlag(usingSingleSlot);
-        }
-
-        ~StructureTransitionTable() {
-            if (!usingSingleTransitionSlot())
-                delete table();
-        }
-
-        // 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;
-        inline bool hasTransition(const StructureTransitionTableHash::Key& key) const;
-        void remove(const StructureTransitionTableHash::Key& key, JSCell* specificValue)
-        {
-            if (usingSingleTransitionSlot()) {
-                ASSERT(contains(key, specificValue));
-                setSingleTransition(0);
-                return;
-            }
-            TransitionTable::iterator find = table()->find(key);
-            if (!specificValue)
-                find->second.first = 0;
-            else
-                find->second.second = 0;
-            if (!find->second.first && !find->second.second)
-                table()->remove(find);
-        }
-        void add(const StructureTransitionTableHash::Key& key, Structure* structure, JSCell* specificValue)
-        {
-            if (usingSingleTransitionSlot()) {
-                if (!singleTransition()) {
-                    setSingleTransition(structure);
-                    return;
-                }
-                reifySingleTransition();
-            }
-            if (!specificValue) {
-                TransitionTable::iterator find = table()->find(key);
-                if (find == table()->end())
-                    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(!table()->contains(key));
-                table()->add(key, Transition(0, structure));
-            }
-        }
-
-    private:
-        TransitionTable* table() const { ASSERT(!usingSingleTransitionSlot()); return m_transitions.m_table; }
-        Structure* singleTransition() const {
-            ASSERT(usingSingleTransitionSlot());
-            return m_transitions.m_singleTransition.get();
-        }
-        bool usingSingleTransitionSlot() const { return m_transitions.m_singleTransition.isFlagSet(usingSingleSlot); }
-        void setSingleTransition(Structure* structure)
-        { 
-            ASSERT(usingSingleTransitionSlot());
-            m_transitions.m_singleTransition.set(structure);
-        }
-
-        void setTransitionTable(TransitionTable* table)
-        {
-            ASSERT(usingSingleTransitionSlot());
-#ifndef NDEBUG
-            setSingleTransition(0);
-#endif
-            m_transitions.m_table = table;
-            // This implicitly clears the flag that indicates we're using a single transition
-            ASSERT(!usingSingleTransitionSlot());
-        }
-        inline void reifySingleTransition();
-
-        enum UsingSingleSlot {
-            usingSingleSlot
-        };
-        // Last bit indicates whether we are using the single transition optimisation
-        union {
-            TransitionTable* m_table;
-            PtrAndFlagsBase<Structure, UsingSingleSlot> m_singleTransition;
-        } m_transitions;
-    };
-
 } // namespace JSC
 
 #endif // StructureTransitionTable_h
 } // namespace JSC
 
 #endif // StructureTransitionTable_h
diff --git a/runtime/Terminator.h b/runtime/Terminator.h
new file mode 100644 (file)
index 0000000..6b0f236
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010 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:
+ *
+ * 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 Google Inc. ("Google") 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 Terminator_h
+#define Terminator_h
+
+namespace JSC {
+
+class Terminator {
+public:
+    Terminator() : m_shouldTerminate(false) { }
+
+    void terminateSoon() { m_shouldTerminate = true; }
+    bool shouldTerminate() const { return m_shouldTerminate; }
+
+private:
+    bool m_shouldTerminate;
+};
+
+} // namespace JSC
+
+#endif // Terminator_h
index 77dfdfc40bd081105baa3d231daec621a9d77226..2a8acced8d12c8f1d15066a36f78c3a80a8bca35 100644 (file)
@@ -84,6 +84,13 @@ static inline unsigned getCPUTime()
     GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
     
     return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
     GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
     
     return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
+#elif OS(SYMBIAN)
+    RThread current;
+    TTimeIntervalMicroSeconds cpuTime;
+
+    TInt err = current.GetCpuTime(cpuTime);
+    ASSERT_WITH_MESSAGE(err == KErrNone, "GetCpuTime failed with %d", err);
+    return cpuTime.Int64() / 1000;
 #elif PLATFORM(BREWMP)
     // This function returns a continuously and linearly increasing millisecond
     // timer from the time the device was powered on.
 #elif PLATFORM(BREWMP)
     // This function returns a continuously and linearly increasing millisecond
     // timer from the time the device was powered on.
index 54eac6a7228924eab3a5028d0d2587a0ce17a744..8f17a3e010ceb7797e73ba7484dc6b1a6a38fc58 100644 (file)
@@ -53,180 +53,35 @@ using namespace WTF::Unicode;
 using namespace std;
 
 namespace JSC {
 using namespace std;
 
 namespace JSC {
+
 extern const double NaN;
 extern const double Inf;
 
 extern const double NaN;
 extern const double Inf;
 
-CString::CString(const char* c)
-    : m_length(strlen(c))
-    , m_data(new char[m_length + 1])
-{
-    memcpy(m_data, c, m_length + 1);
-}
-
-CString::CString(const char* c, size_t length)
-    : m_length(length)
-    , m_data(new char[length + 1])
-{
-    memcpy(m_data, c, m_length);
-    m_data[m_length] = 0;
-}
-
-CString::CString(const CString& b)
-{
-    m_length = b.m_length;
-    if (b.m_data) {
-        m_data = new char[m_length + 1];
-        memcpy(m_data, b.m_data, m_length + 1);
-    } else
-        m_data = 0;
-}
-
-CString::~CString()
-{
-    delete [] m_data;
-}
-
-CString CString::adopt(char* c, size_t length)
-{
-    CString s;
-    s.m_data = c;
-    s.m_length = length;
-    return s;
-}
-
-CString& CString::append(const CString& t)
-{
-    char* n;
-    n = new char[m_length + t.m_length + 1];
-    if (m_length)
-        memcpy(n, m_data, m_length);
-    if (t.m_length)
-        memcpy(n + m_length, t.m_data, t.m_length);
-    m_length += t.m_length;
-    n[m_length] = 0;
-
-    delete [] m_data;
-    m_data = n;
-
-    return *this;
-}
-
-CString& CString::operator=(const char* c)
-{
-    if (m_data)
-        delete [] m_data;
-    m_length = strlen(c);
-    m_data = new char[m_length + 1];
-    memcpy(m_data, c, m_length + 1);
-
-    return *this;
-}
-
-CString& CString::operator=(const CString& str)
-{
-    if (this == &str)
-        return *this;
-
-    if (m_data)
-        delete [] m_data;
-    m_length = str.m_length;
-    if (str.m_data) {
-        m_data = new char[m_length + 1];
-        memcpy(m_data, str.m_data, m_length + 1);
-    } else
-        m_data = 0;
-
-    return *this;
-}
-
-bool operator==(const CString& c1, const CString& c2)
-{
-    size_t len = c1.size();
-    return len == c2.size() && (len == 0 || memcmp(c1.c_str(), c2.c_str(), len) == 0);
-}
-
-// These static strings are immutable, except for rc, whose initial value is chosen to 
-// reduce the possibility of it becoming zero due to ref/deref not being thread-safe.
-static UChar sharedEmptyChar;
-UStringImpl* UStringImpl::s_null;
-UStringImpl* UStringImpl::s_empty;
-UString* UString::nullUString;
+// The null string is immutable, except for refCount.
+UString* UString::s_nullUString;
 
 void initializeUString()
 {
 
 void initializeUString()
 {
-    UStringImpl::s_null = new UStringImpl(0, 0, UStringImpl::ConstructStaticString);
-    UStringImpl::s_empty = new UStringImpl(&sharedEmptyChar, 0, UStringImpl::ConstructStaticString);
-    UString::nullUString = new UString;
-}
-
-static PassRefPtr<UString::Rep> createRep(const char* c)
-{
-    if (!c)
-        return &UString::Rep::null();
-
-    if (!c[0])
-        return &UString::Rep::empty();
-
-    size_t length = strlen(c);
-    UChar* d;
-    PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d);
-    if (!result)
-        return &UString::Rep::null();
-
-    for (size_t i = 0; i < length; i++)
-        d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
-    return result;
-}
-
-static inline PassRefPtr<UString::Rep> createRep(const char* c, int length)
-{
-    if (!c)
-        return &UString::Rep::null();
-
-    if (!length)
-        return &UString::Rep::empty();
-
-    UChar* d;
-    PassRefPtr<UStringImpl> result = UStringImpl::tryCreateUninitialized(length, d);
-    if (!result)
-        return &UString::Rep::null();
+    // UStringImpl::empty() does not construct its static string in a threadsafe fashion,
+    // so ensure it has been initialized from here.
+    UStringImpl::empty();
 
 
-    for (int i = 0; i < length; i++)
-        d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
-    return result;
+    UString::s_nullUString = new UString;
 }
 
 UString::UString(const char* c)
 }
 
 UString::UString(const char* c)
-    : m_rep(createRep(c))
+    : m_rep(Rep::create(c))
 {
 }
 
 {
 }
 
-UString::UString(const char* c, int length)
-    : m_rep(createRep(c, length))
+UString::UString(const char* c, unsigned length)
+    : m_rep(Rep::create(c, length))
 {
 }
 
 {
 }
 
-UString::UString(const UChar* c, int length)
+UString::UString(const UChar* c, unsigned length)
+    : m_rep(Rep::create(c, length))
 {
 {
-    if (length == 0) 
-        m_rep = &Rep::empty();
-    else
-        m_rep = Rep::create(c, length);
-}
-
-UString UString::createFromUTF8(const char* string)
-{
-    if (!string)
-        return null();
-
-    size_t length = strlen(string);
-    Vector<UChar, 1024> buffer(length);
-    UChar* p = buffer.data();
-    if (conversionOK != convertUTF8ToUTF16(&string, string + length, &p, p + length))
-        return null();
-
-    return UString(buffer.data(), p - buffer.data());
 }
 
 UString UString::from(int i)
 }
 
 UString UString::from(int i)
@@ -234,7 +89,7 @@ UString UString::from(int i)
     UChar buf[1 + sizeof(i) * 3];
     UChar* end = buf + sizeof(buf) / sizeof(UChar);
     UChar* p = end;
     UChar buf[1 + sizeof(i) * 3];
     UChar* end = buf + sizeof(buf) / sizeof(UChar);
     UChar* p = end;
-  
+
     if (i == 0)
         *--p = '0';
     else if (i == INT_MIN) {
     if (i == 0)
         *--p = '0';
     else if (i == INT_MIN) {
@@ -255,7 +110,7 @@ UString UString::from(int i)
             *--p = '-';
     }
 
             *--p = '-';
     }
 
-    return UString(p, static_cast<int>(end - p));
+    return UString(p, static_cast<unsigned>(end - p));
 }
 
 UString UString::from(long long i)
 }
 
 UString UString::from(long long i)
@@ -268,13 +123,7 @@ UString UString::from(long long i)
         *--p = '0';
     else if (i == std::numeric_limits<long long>::min()) {
         char minBuf[1 + sizeof(i) * 3];
         *--p = '0';
     else if (i == std::numeric_limits<long long>::min()) {
         char minBuf[1 + sizeof(i) * 3];
-#if OS(WINDOWS)
-        snprintf(minBuf, sizeof(minBuf) - 1, "%I64d", std::numeric_limits<long long>::min());
-#elif PLATFORM(IPHONE)
         snprintf(minBuf, sizeof(minBuf), "%lld", std::numeric_limits<long long>::min());
         snprintf(minBuf, sizeof(minBuf), "%lld", std::numeric_limits<long long>::min());
-#else
-        snprintf(minBuf, sizeof(minBuf) - 1, "%lld", std::numeric_limits<long long>::min());
-#endif
         return UString(minBuf);
     } else {
         bool negative = false;
         return UString(minBuf);
     } else {
         bool negative = false;
@@ -290,15 +139,15 @@ UString UString::from(long long i)
             *--p = '-';
     }
 
             *--p = '-';
     }
 
-    return UString(p, static_cast<int>(end - p));
+    return UString(p, static_cast<unsigned>(end - p));
 }
 
 }
 
-UString UString::from(unsigned int u)
+UString UString::from(unsigned u)
 {
     UChar buf[sizeof(u) * 3];
     UChar* end = buf + sizeof(buf) / sizeof(UChar);
     UChar* p = end;
 {
     UChar buf[sizeof(u) * 3];
     UChar* end = buf + sizeof(buf) / sizeof(UChar);
     UChar* p = end;
-    
+
     if (u == 0)
         *--p = '0';
     else {
     if (u == 0)
         *--p = '0';
     else {
@@ -307,8 +156,8 @@ UString UString::from(unsigned int u)
             u /= 10;
         }
     }
             u /= 10;
         }
     }
-    
-    return UString(p, static_cast<int>(end - p));
+
+    return UString(p, static_cast<unsigned>(end - p));
 }
 
 UString UString::from(long l)
 }
 
 UString UString::from(long l)
@@ -337,7 +186,7 @@ UString UString::from(long l)
             *--p = '-';
     }
 
             *--p = '-';
     }
 
-    return UString(p, static_cast<int>(end - p));
+    return UString(p, end - p);
 }
 
 UString UString::from(double d)
 }
 
 UString UString::from(double d)
@@ -348,100 +197,12 @@ UString UString::from(double d)
     return UString(buffer, length);
 }
 
     return UString(buffer, length);
 }
 
-UString UString::spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const
-{
-    m_rep->checkConsistency();
-
-    if (rangeCount == 1 && separatorCount == 0) {
-        int thisSize = size();
-        int position = substringRanges[0].position;
-        int length = substringRanges[0].length;
-        if (position <= 0 && length >= thisSize)
-            return *this;
-        return UString::Rep::create(m_rep, max(0, position), min(thisSize, length));
-    }
-
-    int totalLength = 0;
-    for (int i = 0; i < rangeCount; i++)
-        totalLength += substringRanges[i].length;
-    for (int i = 0; i < separatorCount; i++)
-        totalLength += separators[i].size();
-
-    if (totalLength == 0)
-        return "";
-
-    UChar* buffer;
-    PassRefPtr<Rep> rep = Rep::tryCreateUninitialized(totalLength, buffer);
-    if (!rep)
-        return null();
-
-    int maxCount = max(rangeCount, separatorCount);
-    int bufferPos = 0;
-    for (int i = 0; i < maxCount; i++) {
-        if (i < rangeCount) {
-            UStringImpl::copyChars(buffer + bufferPos, data() + substringRanges[i].position, substringRanges[i].length);
-            bufferPos += substringRanges[i].length;
-        }
-        if (i < separatorCount) {
-            UStringImpl::copyChars(buffer + bufferPos, separators[i].data(), separators[i].size());
-            bufferPos += separators[i].size();
-        }
-    }
-
-    return rep;
-}
-
-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;
-    PassRefPtr<Rep> rep = Rep::tryCreateUninitialized(totalLength, buffer);
-    if (!rep)
-        return null();
-
-    UStringImpl::copyChars(buffer, data(), rangeStart);
-    UStringImpl::copyChars(buffer + rangeStart, replacement.data(), replacementLength);
-    int rangeEnd = rangeStart + rangeLength;
-    UStringImpl::copyChars(buffer + rangeStart + replacementLength, data() + rangeEnd, size() - rangeEnd);
-
-    return rep;
-}
-
-bool UString::getCString(CStringBuffer& buffer) const
-{
-    int length = size();
-    int neededSize = length + 1;
-    buffer.resize(neededSize);
-    char* buf = buffer.data();
-
-    UChar ored = 0;
-    const UChar* p = data();
-    char* q = buf;
-    const UChar* limit = p + length;
-    while (p != limit) {
-        UChar c = p[0];
-        ored |= c;
-        *q = static_cast<char>(c);
-        ++p;
-        ++q;
-    }
-    *q = '\0';
-
-    return !(ored & 0xFF00);
-}
-
 char* UString::ascii() const
 {
     static char* asciiBuffer = 0;
 
 char* UString::ascii() const
 {
     static char* asciiBuffer = 0;
 
-    int length = size();
-    int neededSize = length + 1;
+    unsigned length = size();
+    unsigned neededSize = length + 1;
     delete[] asciiBuffer;
     asciiBuffer = new char[neededSize];
 
     delete[] asciiBuffer;
     asciiBuffer = new char[neededSize];
 
@@ -458,30 +219,6 @@ char* UString::ascii() const
     return asciiBuffer;
 }
 
     return asciiBuffer;
 }
 
-UString& UString::operator=(const char* c)
-{
-    if (!c) {
-        m_rep = &Rep::null();
-        return *this;
-    }
-
-    if (!c[0]) {
-        m_rep = &Rep::empty();
-        return *this;
-    }
-
-    int l = static_cast<int>(strlen(c));
-    UChar* d = 0;
-    m_rep = Rep::tryCreateUninitialized(l, d);
-    if (m_rep) {
-        for (int i = 0; i < l; i++)
-            d[i] = static_cast<unsigned char>(c[i]); // use unsigned char to zero-extend instead of sign-extend
-    } else
-        makeNull();
-
-    return *this;
-}
-
 bool UString::is8Bit() const
 {
     const UChar* u = data();
 bool UString::is8Bit() const
 {
     const UChar* u = data();
@@ -495,7 +232,7 @@ bool UString::is8Bit() const
     return true;
 }
 
     return true;
 }
 
-UChar UString::operator[](int pos) const
+UChar UString::operator[](unsigned pos) const
 {
     if (pos >= size())
         return '\0';
 {
     if (pos >= size())
         return '\0';
@@ -513,10 +250,14 @@ double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) co
         return NaN;
     }
 
         return NaN;
     }
 
-    // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk
-    // after the number, so this is too strict a check.
-    CStringBuffer s;
-    if (!getCString(s))
+    // FIXME: If tolerateTrailingJunk is true, then we want to tolerate junk 
+    // after the number, even if it contains invalid UTF-16 sequences. So we
+    // shouldn't use the UTF8String function, which returns null when it
+    // encounters invalid UTF-16. Further, we have no need to convert the
+    // non-ASCII characters to UTF-8, so the UTF8String does quite a bit of
+    // unnecessary work.
+    CString s = UTF8String();
+    if (s.isNull())
         return NaN;
     const char* c = s.data();
 
         return NaN;
     const char* c = s.data();
 
@@ -581,6 +322,7 @@ double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) co
     while (isASCIISpace(*c))
         c++;
     // don't allow anything after - unless tolerant=true
     while (isASCIISpace(*c))
         c++;
     // don't allow anything after - unless tolerant=true
+    // FIXME: If string contains a U+0000 character, then this check is incorrect.
     if (!tolerateTrailingJunk && *c != '\0')
         d = NaN;
 
     if (!tolerateTrailingJunk && *c != '\0')
         d = NaN;
 
@@ -635,10 +377,10 @@ uint32_t UString::toStrictUInt32(bool* ok) const
         *ok = false;
 
     // Empty string is not OK.
         *ok = false;
 
     // Empty string is not OK.
-    int len = m_rep->size();
+    unsigned len = m_rep->length();
     if (len == 0)
         return 0;
     if (len == 0)
         return 0;
-    const UChar* p = m_rep->data();
+    const UChar* p = m_rep->characters();
     unsigned short c = p[0];
 
     // If the first digit is 0, only 0 itself is OK.
     unsigned short c = p[0];
 
     // If the first digit is 0, only 0 itself is OK.
@@ -679,102 +421,92 @@ uint32_t UString::toStrictUInt32(bool* ok) const
     }
 }
 
     }
 }
 
-int UString::find(const UString& f, int pos) const
+unsigned UString::find(const UString& f, unsigned pos) const
 {
 {
-    int fsz = f.size();
-
-    if (pos < 0)
-        pos = 0;
+    unsigned fsz = f.size();
 
     if (fsz == 1) {
         UChar ch = f[0];
         const UChar* end = data() + size();
         for (const UChar* c = data() + pos; c < end; c++) {
             if (*c == ch)
 
     if (fsz == 1) {
         UChar ch = f[0];
         const UChar* end = data() + size();
         for (const UChar* c = data() + pos; c < end; c++) {
             if (*c == ch)
-                return static_cast<int>(c - data());
+                return static_cast<unsigned>(c - data());
         }
         }
-        return -1;
+        return NotFound;
     }
 
     }
 
-    int sz = size();
+    unsigned sz = size();
     if (sz < fsz)
     if (sz < fsz)
-        return -1;
+        return NotFound;
     if (fsz == 0)
         return pos;
     const UChar* end = data() + sz - fsz;
     if (fsz == 0)
         return pos;
     const UChar* end = data() + sz - fsz;
-    int fsizeminusone = (fsz - 1) * sizeof(UChar);
+    unsigned fsizeminusone = (fsz - 1) * sizeof(UChar);
     const UChar* fdata = f.data();
     unsigned short fchar = fdata[0];
     ++fdata;
     for (const UChar* c = data() + pos; c <= end; c++) {
         if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))
     const UChar* fdata = f.data();
     unsigned short fchar = fdata[0];
     ++fdata;
     for (const UChar* c = data() + pos; c <= end; c++) {
         if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))
-            return static_cast<int>(c - data());
+            return static_cast<unsigned>(c - data());
     }
 
     }
 
-    return -1;
+    return NotFound;
 }
 
 }
 
-int UString::find(UChar ch, int pos) const
+unsigned UString::find(UChar ch, unsigned pos) const
 {
 {
-    if (pos < 0)
-        pos = 0;
     const UChar* end = data() + size();
     for (const UChar* c = data() + pos; c < end; c++) {
         if (*c == ch)
     const UChar* end = data() + size();
     for (const UChar* c = data() + pos; c < end; c++) {
         if (*c == ch)
-            return static_cast<int>(c - data());
+            return static_cast<unsigned>(c - data());
     }
     }
-    
-    return -1;
+
+    return NotFound;
 }
 
 }
 
-int UString::rfind(const UString& f, int pos) const
+unsigned UString::rfind(const UString& f, unsigned pos) const
 {
 {
-    int sz = size();
-    int fsz = f.size();
+    unsigned sz = size();
+    unsigned fsz = f.size();
     if (sz < fsz)
     if (sz < fsz)
-        return -1;
-    if (pos < 0)
-        pos = 0;
+        return NotFound;
     if (pos > sz - fsz)
         pos = sz - fsz;
     if (fsz == 0)
         return pos;
     if (pos > sz - fsz)
         pos = sz - fsz;
     if (fsz == 0)
         return pos;
-    int fsizeminusone = (fsz - 1) * sizeof(UChar);
+    unsigned fsizeminusone = (fsz - 1) * sizeof(UChar);
     const UChar* fdata = f.data();
     for (const UChar* c = data() + pos; c >= data(); c--) {
         if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
     const UChar* fdata = f.data();
     for (const UChar* c = data() + pos; c >= data(); c--) {
         if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
-            return static_cast<int>(c - data());
+            return static_cast<unsigned>(c - data());
     }
 
     }
 
-    return -1;
+    return NotFound;
 }
 
 }
 
-int UString::rfind(UChar ch, int pos) const
+unsigned UString::rfind(UChar ch, unsigned pos) const
 {
     if (isEmpty())
 {
     if (isEmpty())
-        return -1;
+        return NotFound;
     if (pos + 1 >= size())
         pos = size() - 1;
     for (const UChar* c = data() + pos; c >= data(); c--) {
         if (*c == ch)
     if (pos + 1 >= size())
         pos = size() - 1;
     for (const UChar* c = data() + pos; c >= data(); c--) {
         if (*c == ch)
-            return static_cast<int>(c - data());
+            return static_cast<unsigned>(c - data());
     }
 
     }
 
-    return -1;
+    return NotFound;
 }
 
 }
 
-UString UString::substr(int pos, int len) const
+UString UString::substr(unsigned pos, unsigned len) const
 {
 {
-    int s = size();
+    unsigned s = size();
 
 
-    if (pos < 0)
-        pos = 0;
-    else if (pos >= s)
+    if (pos >= s)
         pos = s;
         pos = s;
-    if (len < 0)
-        len = s;
-    if (pos + len >= s)
-        len = s - pos;
+    unsigned limit = s - pos;
+    if (len > limit)
+        len = limit;
 
     if (pos == 0 && len == s)
         return *this;
 
     if (pos == 0 && len == s)
         return *this;
@@ -801,12 +533,12 @@ bool operator==(const UString& s1, const char *s2)
 
 bool operator<(const UString& s1, const UString& s2)
 {
 
 bool operator<(const UString& s1, const UString& s2)
 {
-    const int l1 = s1.size();
-    const int l2 = s2.size();
-    const int lmin = l1 < l2 ? l1 : l2;
+    const unsigned l1 = s1.size();
+    const unsigned l2 = s2.size();
+    const unsigned lmin = l1 < l2 ? l1 : l2;
     const UChar* c1 = s1.data();
     const UChar* c2 = s2.data();
     const UChar* c1 = s1.data();
     const UChar* c2 = s2.data();
-    int l = 0;
+    unsigned l = 0;
     while (l < lmin && *c1 == *c2) {
         c1++;
         c2++;
     while (l < lmin && *c1 == *c2) {
         c1++;
         c2++;
@@ -820,12 +552,12 @@ bool operator<(const UString& s1, const UString& s2)
 
 bool operator>(const UString& s1, const UString& s2)
 {
 
 bool operator>(const UString& s1, const UString& s2)
 {
-    const int l1 = s1.size();
-    const int l2 = s2.size();
-    const int lmin = l1 < l2 ? l1 : l2;
+    const unsigned l1 = s1.size();
+    const unsigned l2 = s2.size();
+    const unsigned lmin = l1 < l2 ? l1 : l2;
     const UChar* c1 = s1.data();
     const UChar* c2 = s2.data();
     const UChar* c1 = s1.data();
     const UChar* c2 = s2.data();
-    int l = 0;
+    unsigned l = 0;
     while (l < lmin && *c1 == *c2) {
         c1++;
         c2++;
     while (l < lmin && *c1 == *c2) {
         c1++;
         c2++;
@@ -839,12 +571,12 @@ bool operator>(const UString& s1, const UString& s2)
 
 int compare(const UString& s1, const UString& s2)
 {
 
 int compare(const UString& s1, const UString& s2)
 {
-    const int l1 = s1.size();
-    const int l2 = s2.size();
-    const int lmin = l1 < l2 ? l1 : l2;
+    const unsigned l1 = s1.size();
+    const unsigned l2 = s2.size();
+    const unsigned lmin = l1 < l2 ? l1 : l2;
     const UChar* c1 = s1.data();
     const UChar* c2 = s2.data();
     const UChar* c1 = s1.data();
     const UChar* c2 = s2.data();
-    int l = 0;
+    unsigned l = 0;
     while (l < lmin && *c1 == *c2) {
         c1++;
         c2++;
     while (l < lmin && *c1 == *c2) {
         c1++;
         c2++;
@@ -860,24 +592,10 @@ int compare(const UString& s1, const UString& s2)
     return (l1 > l2) ? 1 : -1;
 }
 
     return (l1 > l2) ? 1 : -1;
 }
 
-bool equal(const UString::Rep* r, const UString::Rep* b)
-{
-    int length = r->size();
-    if (length != b->size())
-        return false;
-    const UChar* d = r->data();
-    const UChar* s = b->data();
-    for (int i = 0; i != length; ++i) {
-        if (d[i] != s[i])
-            return false;
-    }
-    return true;
-}
-
 CString UString::UTF8String(bool strict) const
 {
     // Allocate a buffer big enough to hold all the characters.
 CString UString::UTF8String(bool strict) const
 {
     // Allocate a buffer big enough to hold all the characters.
-    const int length = size();
+    const unsigned length = size();
     Vector<char, 1024> buffer(length * 3);
 
     // Convert to runs of 8-bit characters.
     Vector<char, 1024> buffer(length * 3);
 
     // Convert to runs of 8-bit characters.
@@ -890,16 +608,4 @@ CString UString::UTF8String(bool strict) const
     return CString(buffer.data(), p - buffer.data());
 }
 
     return CString(buffer.data(), p - buffer.data());
 }
 
-// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
-NEVER_INLINE void UString::makeNull()
-{
-    m_rep = &Rep::null();
-}
-
-// For use in error handling code paths -- having this not be inlined helps avoid PIC branches to fetch the global on Mac OS X.
-NEVER_INLINE UString::Rep* UString::nullRep()
-{
-    return &Rep::null();
-}
-
 } // namespace JSC
 } // namespace JSC
index 0c13689a703b7cc978957684d44913e24a85bfa0..e3cd7a107f7cebdeada36f112fb22508df907437 100644 (file)
@@ -31,9 +31,9 @@
 #include <wtf/CrossThreadRefCounted.h>
 #include <wtf/OwnFastMallocPtr.h>
 #include <wtf/PassRefPtr.h>
 #include <wtf/CrossThreadRefCounted.h>
 #include <wtf/OwnFastMallocPtr.h>
 #include <wtf/PassRefPtr.h>
-#include <wtf/PtrAndFlags.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
 #include <wtf/RefPtr.h>
 #include <wtf/Vector.h>
+#include <wtf/text/CString.h>
 #include <wtf/unicode/Unicode.h>
 
 namespace JSC {
 #include <wtf/unicode/Unicode.h>
 
 namespace JSC {
@@ -41,39 +41,6 @@ namespace JSC {
     using WTF::PlacementNewAdoptType;
     using WTF::PlacementNewAdopt;
 
     using WTF::PlacementNewAdoptType;
     using WTF::PlacementNewAdopt;
 
-    class CString {
-    public:
-        CString()
-            : m_length(0)
-            , m_data(0)
-        {
-        }
-
-        CString(const char*);
-        CString(const char*, size_t);
-        CString(const CString&);
-
-        ~CString();
-
-        static CString adopt(char*, size_t); // buffer should be allocated with new[].
-
-        CString& append(const CString&);
-        CString& operator=(const char* c);
-        CString& operator=(const CString&);
-        CString& operator+=(const CString& c) { return append(c); }
-
-        size_t size() const { return m_length; }
-        const char* c_str() const { return m_data; }
-
-    private:
-        size_t m_length;
-        char* m_data;
-    };
-
-    bool operator==(const CString&, const CString&);
-
-    typedef Vector<char, 32> CStringBuffer;
-
     class UString {
         friend class JIT;
 
     class UString {
         friend class JIT;
 
@@ -81,11 +48,10 @@ namespace JSC {
         typedef UStringImpl Rep;
     
     public:
         typedef UStringImpl Rep;
     
     public:
-        // UString constructors passed char*s assume ISO Latin-1 encoding; for UTF8 use 'createFromUTF8', below.
-        UString();
+        UString() {}
         UString(const char*); // Constructor for null-terminated string.
         UString(const char*); // Constructor for null-terminated string.
-        UString(const char*, int length);
-        UString(const UChar*, int length);
+        UString(const char*, unsigned length);
+        UString(const UChar*, unsigned length);
         UString(const Vector<UChar>& buffer);
 
         UString(const UString& s)
         UString(const Vector<UChar>& buffer);
 
         UString(const UString& s)
@@ -99,46 +65,18 @@ namespace JSC {
         {
         }
 
         {
         }
 
-        ~UString()
-        {
-        }
-
         template<size_t inlineCapacity>
         static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
         {
             return Rep::adopt(vector);
         }
 
         template<size_t inlineCapacity>
         static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
         {
             return Rep::adopt(vector);
         }
 
-        static UString createFromUTF8(const char*);
-
         static UString from(int);
         static UString from(long long);
         static UString from(int);
         static UString from(long long);
-        static UString from(unsigned int);
+        static UString from(unsigned);
         static UString from(long);
         static UString from(double);
 
         static UString from(long);
         static UString from(double);
 
-        struct Range {
-        public:
-            Range(int pos, int len)
-                : position(pos)
-                , length(len)
-            {
-            }
-
-            Range()
-            {
-            }
-
-            int position;
-            int length;
-        };
-
-        UString spliceSubstringsWithSeparators(const Range* substringRanges, int rangeCount, const UString* separators, int separatorCount) const;
-
-        UString replaceRange(int rangeStart, int RangeEnd, const UString& replacement) const;
-
-        bool getCString(CStringBuffer&) const;
-
         // NOTE: This method should only be used for *debugging* purposes as it
         // is neither Unicode safe nor free from side effects nor thread-safe.
         char* ascii() const;
         // NOTE: This method should only be used for *debugging* purposes as it
         // is neither Unicode safe nor free from side effects nor thread-safe.
         char* ascii() const;
@@ -153,18 +91,26 @@ namespace JSC {
          */
         CString UTF8String(bool strict = false) const;
 
          */
         CString UTF8String(bool strict = false) const;
 
-        UString& operator=(const char*c);
+        const UChar* data() const
+        {
+            if (!m_rep)
+                return 0;
+            return m_rep->characters();
+        }
 
 
-        const UChar* data() const { return m_rep->data(); }
+        unsigned size() const
+        {
+            if (!m_rep)
+                return 0;
+            return m_rep->length();
+        }
 
 
-        bool isNull() const { return m_rep == &Rep::null(); }
-        bool isEmpty() const { return !m_rep->size(); }
+        bool isNull() const { return !m_rep; }
+        bool isEmpty() const { return !m_rep || !m_rep->length(); }
 
         bool is8Bit() const;
 
 
         bool is8Bit() const;
 
-        int size() const { return m_rep->size(); }
-
-        UChar operator[](int pos) const;
+        UChar operator[](unsigned pos) const;
 
         double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const;
         double toDouble(bool tolerateTrailingJunk) const;
 
         double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const;
         double toDouble(bool tolerateTrailingJunk) const;
@@ -176,31 +122,34 @@ namespace JSC {
 
         unsigned toArrayIndex(bool* ok = 0) const;
 
 
         unsigned toArrayIndex(bool* ok = 0) const;
 
-        int find(const UString& f, int pos = 0) const;
-        int find(UChar, int pos = 0) const;
-        int rfind(const UString& f, int pos) const;
-        int rfind(UChar, int pos) const;
+        static const unsigned NotFound = 0xFFFFFFFFu;
+        unsigned find(const UString& f, unsigned pos = 0) const;
+        unsigned find(UChar, unsigned pos = 0) const;
+        unsigned rfind(const UString& f, unsigned pos) const;
+        unsigned rfind(UChar, unsigned pos) const;
 
 
-        UString substr(int pos = 0, int len = -1) const;
+        UString substr(unsigned pos = 0, unsigned len = 0xFFFFFFFF) const;
 
 
-        static const UString& null() { return *nullUString; }
+        static const UString& null() { return *s_nullUString; }
 
         Rep* rep() const { return m_rep.get(); }
 
         Rep* rep() const { return m_rep.get(); }
-        static Rep* nullRep();
 
         UString(PassRefPtr<Rep> r)
             : m_rep(r)
         {
 
         UString(PassRefPtr<Rep> r)
             : m_rep(r)
         {
-            ASSERT(m_rep);
         }
 
         }
 
-        size_t cost() const { return m_rep->cost(); }
+        size_t cost() const
+        {
+            if (!m_rep)
+                return 0;
+            return m_rep->cost();
+        }
 
     private:
 
     private:
-        void makeNull();
-
         RefPtr<Rep> m_rep;
         RefPtr<Rep> m_rep;
-        static UString* nullUString;
+
+        static UString* s_nullUString;
 
         friend void initializeUString();
         friend bool operator==(const UString&, const UString&);
 
         friend void initializeUString();
         friend bool operator==(const UString&, const UString&);
@@ -208,21 +157,43 @@ namespace JSC {
 
     ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2)
     {
 
     ALWAYS_INLINE bool operator==(const UString& s1, const UString& s2)
     {
-        int size = s1.size();
-        switch (size) {
-        case 0:
-            return !s2.size();
+        UString::Rep* rep1 = s1.rep();
+        UString::Rep* rep2 = s2.rep();
+        unsigned size1 = 0;
+        unsigned size2 = 0;
+
+        if (rep1 == rep2) // If they're the same rep, they're equal.
+            return true;
+        
+        if (rep1)
+            size1 = rep1->length();
+            
+        if (rep2)
+            size2 = rep2->length();
+            
+        if (size1 != size2) // If the lengths are not the same, we're done.
+            return false;
+        
+        if (!size1)
+            return true;
+        
+        // At this point we know 
+        //   (a) that the strings are the same length and
+        //   (b) that they are greater than zero length.
+        const UChar* d1 = rep1->characters();
+        const UChar* d2 = rep2->characters();
+        
+        if (d1 == d2) // Check to see if the data pointers are the same.
+            return true;
+        
+        // Do quick checks for sizes 1 and 2.
+        switch (size1) {
         case 1:
         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];
+        case 2:
             return (d1[0] == d2[0]) & (d1[1] == d2[1]);
             return (d1[0] == d2[0]) & (d1[1] == d2[1]);
-        }
         default:
         default:
-            return s2.size() == size && memcmp(s1.data(), s2.data(), size * sizeof(UChar)) == 0;
+            return memcmp(d1, d2, size1 * sizeof(UChar)) == 0;
         }
     }
 
         }
     }
 
@@ -254,11 +225,6 @@ namespace JSC {
 
     int compare(const UString&, const UString&);
 
 
     int compare(const UString&, const UString&);
 
-    inline UString::UString()
-        : m_rep(&Rep::null())
-    {
-    }
-
     // Rule from ECMA 15.2 about what an array index is.
     // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
     inline unsigned UString::toArrayIndex(bool* ok) const
     // Rule from ECMA 15.2 about what an array index is.
     // Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
     inline unsigned UString::toArrayIndex(bool* ok) const
@@ -272,9 +238,7 @@ namespace JSC {
     // We'd rather not do shared substring append for small strings, since
     // this runs too much risk of a tiny initial string holding down a
     // huge buffer.
     // We'd rather not do shared substring append for small strings, since
     // this runs too much risk of a tiny initial string holding down a
     // huge buffer.
-    // FIXME: this should be size_t but that would cause warnings until we
-    // fix UString sizes to be size_t instead of int
-    static const int minShareSize = Heap::minExtraCost / sizeof(UChar);
+    static const unsigned minShareSize = Heap::minExtraCost / sizeof(UChar);
 
     struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > {
         static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->existingHash(); }
 
     struct IdentifierRepHash : PtrHash<RefPtr<JSC::UString::Rep> > {
         static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->existingHash(); }
@@ -353,17 +317,29 @@ namespace JSC {
         unsigned m_length;
     };
 
         unsigned m_length;
     };
 
+    inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow)
+    {
+        unsigned oldTotal = total;
+        total = oldTotal + addend;
+        if (total < oldTotal)
+            overflow = true;
+    }
+
     template<typename StringType1, typename StringType2>
     template<typename StringType1, typename StringType2>
-    UString makeString(StringType1 string1, StringType2 string2)
+    PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2)
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
 
         UChar* buffer;
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
 
         UChar* buffer;
-        unsigned length = adapter1.length() + adapter2.length();
+        bool overflow = false;
+        unsigned length = adapter1.length();
+        sumWithOverflow(length, adapter2.length(), overflow);
+        if (overflow)
+            return 0;
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
-            return UString();
+            return 0;
 
         UChar* result = buffer;
         adapter1.writeTo(result);
 
         UChar* result = buffer;
         adapter1.writeTo(result);
@@ -374,17 +350,22 @@ namespace JSC {
     }
 
     template<typename StringType1, typename StringType2, typename StringType3>
     }
 
     template<typename StringType1, typename StringType2, typename StringType3>
-    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
+    PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3)
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
         StringTypeAdapter<StringType3> adapter3(string3);
 
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
         StringTypeAdapter<StringType3> adapter3(string3);
 
-        UChar* buffer;
-        unsigned length = adapter1.length() + adapter2.length() + adapter3.length();
+        UChar* buffer = 0;
+        bool overflow = false;
+        unsigned length = adapter1.length();
+        sumWithOverflow(length, adapter2.length(), overflow);
+        sumWithOverflow(length, adapter3.length(), overflow);
+        if (overflow)
+            return 0;
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
-            return UString();
+            return 0;
 
         UChar* result = buffer;
         adapter1.writeTo(result);
 
         UChar* result = buffer;
         adapter1.writeTo(result);
@@ -397,7 +378,7 @@ namespace JSC {
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
-    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+    PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
@@ -405,10 +386,16 @@ namespace JSC {
         StringTypeAdapter<StringType4> adapter4(string4);
 
         UChar* buffer;
         StringTypeAdapter<StringType4> adapter4(string4);
 
         UChar* buffer;
-        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length();
+        bool overflow = false;
+        unsigned length = adapter1.length();
+        sumWithOverflow(length, adapter2.length(), overflow);
+        sumWithOverflow(length, adapter3.length(), overflow);
+        sumWithOverflow(length, adapter4.length(), overflow);
+        if (overflow)
+            return 0;
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
-            return UString();
+            return 0;
 
         UChar* result = buffer;
         adapter1.writeTo(result);
 
         UChar* result = buffer;
         adapter1.writeTo(result);
@@ -423,7 +410,7 @@ namespace JSC {
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
-    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+    PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
@@ -432,10 +419,17 @@ namespace JSC {
         StringTypeAdapter<StringType5> adapter5(string5);
 
         UChar* buffer;
         StringTypeAdapter<StringType5> adapter5(string5);
 
         UChar* buffer;
-        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length();
+        bool overflow = false;
+        unsigned length = adapter1.length();
+        sumWithOverflow(length, adapter2.length(), overflow);
+        sumWithOverflow(length, adapter3.length(), overflow);
+        sumWithOverflow(length, adapter4.length(), overflow);
+        sumWithOverflow(length, adapter5.length(), overflow);
+        if (overflow)
+            return 0;
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
-            return UString();
+            return 0;
 
         UChar* result = buffer;
         adapter1.writeTo(result);
 
         UChar* result = buffer;
         adapter1.writeTo(result);
@@ -452,7 +446,7 @@ namespace JSC {
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
-    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+    PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
@@ -462,10 +456,18 @@ namespace JSC {
         StringTypeAdapter<StringType6> adapter6(string6);
 
         UChar* buffer;
         StringTypeAdapter<StringType6> adapter6(string6);
 
         UChar* buffer;
-        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length();
+        bool overflow = false;
+        unsigned length = adapter1.length();
+        sumWithOverflow(length, adapter2.length(), overflow);
+        sumWithOverflow(length, adapter3.length(), overflow);
+        sumWithOverflow(length, adapter4.length(), overflow);
+        sumWithOverflow(length, adapter5.length(), overflow);
+        sumWithOverflow(length, adapter6.length(), overflow);
+        if (overflow)
+            return 0;
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
-            return UString();
+            return 0;
 
         UChar* result = buffer;
         adapter1.writeTo(result);
 
         UChar* result = buffer;
         adapter1.writeTo(result);
@@ -484,7 +486,7 @@ namespace JSC {
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
-    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+    PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
@@ -495,10 +497,19 @@ namespace JSC {
         StringTypeAdapter<StringType7> adapter7(string7);
 
         UChar* buffer;
         StringTypeAdapter<StringType7> adapter7(string7);
 
         UChar* buffer;
-        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length();
+        bool overflow = false;
+        unsigned length = adapter1.length();
+        sumWithOverflow(length, adapter2.length(), overflow);
+        sumWithOverflow(length, adapter3.length(), overflow);
+        sumWithOverflow(length, adapter4.length(), overflow);
+        sumWithOverflow(length, adapter5.length(), overflow);
+        sumWithOverflow(length, adapter6.length(), overflow);
+        sumWithOverflow(length, adapter7.length(), overflow);
+        if (overflow)
+            return 0;
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
-            return UString();
+            return 0;
 
         UChar* result = buffer;
         adapter1.writeTo(result);
 
         UChar* result = buffer;
         adapter1.writeTo(result);
@@ -519,7 +530,7 @@ namespace JSC {
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
     }
 
     template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
-    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+    PassRefPtr<UStringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
     {
         StringTypeAdapter<StringType1> adapter1(string1);
         StringTypeAdapter<StringType2> adapter2(string2);
@@ -531,10 +542,20 @@ namespace JSC {
         StringTypeAdapter<StringType8> adapter8(string8);
 
         UChar* buffer;
         StringTypeAdapter<StringType8> adapter8(string8);
 
         UChar* buffer;
-        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length() + adapter8.length();
+        bool overflow = false;
+        unsigned length = adapter1.length();
+        sumWithOverflow(length, adapter2.length(), overflow);
+        sumWithOverflow(length, adapter3.length(), overflow);
+        sumWithOverflow(length, adapter4.length(), overflow);
+        sumWithOverflow(length, adapter5.length(), overflow);
+        sumWithOverflow(length, adapter6.length(), overflow);
+        sumWithOverflow(length, adapter7.length(), overflow);
+        sumWithOverflow(length, adapter8.length(), overflow);
+        if (overflow)
+            return 0;
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
         PassRefPtr<UStringImpl> resultImpl = UStringImpl::tryCreateUninitialized(length, buffer);
         if (!resultImpl)
-            return UString();
+            return 0;
 
         UChar* result = buffer;
         adapter1.writeTo(result);
 
         UChar* result = buffer;
         adapter1.writeTo(result);
@@ -556,6 +577,69 @@ namespace JSC {
         return resultImpl;
     }
 
         return resultImpl;
     }
 
+    template<typename StringType1, typename StringType2>
+    UString makeString(StringType1 string1, StringType2 string2)
+    {
+        PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2);
+        if (!resultImpl)
+            CRASH();
+        return resultImpl;
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
+    {
+        PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3);
+        if (!resultImpl)
+            CRASH();
+        return resultImpl;
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
+    {
+        PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4);
+        if (!resultImpl)
+            CRASH();
+        return resultImpl;
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
+    {
+        PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5);
+        if (!resultImpl)
+            CRASH();
+        return resultImpl;
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
+    {
+        PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6);
+        if (!resultImpl)
+            CRASH();
+        return resultImpl;
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
+    {
+        PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7);
+        if (!resultImpl)
+            CRASH();
+        return resultImpl;
+    }
+
+    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
+    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
+    {
+        PassRefPtr<UStringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8);
+        if (!resultImpl)
+            CRASH();
+        return resultImpl;
+    }
+
 } // namespace JSC
 
 namespace WTF {
 } // namespace JSC
 
 namespace WTF {
@@ -565,7 +649,7 @@ namespace WTF {
 
     template<> struct StrHash<JSC::UString::Rep*> {
         static unsigned hash(const JSC::UString::Rep* key) { return key->hash(); }
 
     template<> struct StrHash<JSC::UString::Rep*> {
         static unsigned hash(const JSC::UString::Rep* key) { return key->hash(); }
-        static bool equal(const JSC::UString::Rep* a, const JSC::UString::Rep* b) { return JSC::equal(a, b); }
+        static bool equal(const JSC::UString::Rep* a, const JSC::UString::Rep* b) { return ::equal(a, b); }
         static const bool safeToCompareToEmptyOrDeleted = false;
     };
 
         static const bool safeToCompareToEmptyOrDeleted = false;
     };
 
@@ -573,22 +657,18 @@ namespace WTF {
         using StrHash<JSC::UString::Rep*>::hash;
         static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->hash(); }
         using StrHash<JSC::UString::Rep*>::equal;
         using StrHash<JSC::UString::Rep*>::hash;
         static unsigned hash(const RefPtr<JSC::UString::Rep>& key) { return key->hash(); }
         using StrHash<JSC::UString::Rep*>::equal;
-        static bool equal(const RefPtr<JSC::UString::Rep>& a, const RefPtr<JSC::UString::Rep>& b) { return JSC::equal(a.get(), b.get()); }
-        static bool equal(const JSC::UString::Rep* a, const RefPtr<JSC::UString::Rep>& b) { return JSC::equal(a, b.get()); }
-        static bool equal(const RefPtr<JSC::UString::Rep>& a, const JSC::UString::Rep* b) { return JSC::equal(a.get(), b); }
+        static bool equal(const RefPtr<JSC::UString::Rep>& a, const RefPtr<JSC::UString::Rep>& b) { return ::equal(a.get(), b.get()); }
+        static bool equal(const JSC::UString::Rep* a, const RefPtr<JSC::UString::Rep>& b) { return ::equal(a, b.get()); }
+        static bool equal(const RefPtr<JSC::UString::Rep>& a, const JSC::UString::Rep* b) { return ::equal(a.get(), b); }
 
         static const bool safeToCompareToEmptyOrDeleted = false;
     };
 
 
         static const bool safeToCompareToEmptyOrDeleted = false;
     };
 
-    template<> struct DefaultHash<JSC::UString::Rep*> {
-        typedef StrHash<JSC::UString::Rep*> Hash;
-    };
-
-    template<> struct DefaultHash<RefPtr<JSC::UString::Rep> > {
-        typedef StrHash<RefPtr<JSC::UString::Rep> > Hash;
-
+    template <> struct VectorTraits<JSC::UString> : SimpleClassVectorTraits
+    {
+        static const bool canInitializeWithMemset = true;
     };
     };
-
+    
 } // namespace WTF
 
 #endif
 } // namespace WTF
 
 #endif
diff --git a/runtime/UStringImpl.cpp b/runtime/UStringImpl.cpp
deleted file mode 100644 (file)
index 4b0d1c9..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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 "UStringImpl.h"
-
-#include "Identifier.h"
-#include "UString.h"
-#include <wtf/unicode/UTF8.h>
-
-using namespace WTF::Unicode;
-using namespace std;
-
-namespace JSC {
-SharedUChar* UStringImpl::baseSharedBuffer()
-{
-    ASSERT((bufferOwnership() == BufferShared)
-        || ((bufferOwnership() == BufferOwned) && !m_dataBuffer.asPtr<void*>()));
-
-    if (bufferOwnership() != BufferShared)
-        m_dataBuffer = UntypedPtrAndBitfield(SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef(), BufferShared);
-
-    return m_dataBuffer.asPtr<SharedUChar*>();
-}
-
-SharedUChar* UStringImpl::sharedBuffer()
-{
-    if (m_length < s_minLengthToShare)
-        return 0;
-    ASSERT(!isStatic());
-
-    UStringImpl* owner = bufferOwnerString();
-    if (owner->bufferOwnership() == BufferInternal)
-        return 0;
-
-    return owner->baseSharedBuffer();
-}
-
-UStringImpl::~UStringImpl()
-{
-    ASSERT(!isStatic());
-    checkConsistency();
-
-    if (isIdentifier())
-        Identifier::remove(this);
-
-    if (bufferOwnership() != BufferInternal) {
-        if (bufferOwnership() == BufferOwned)
-            fastFree(m_data);
-        else if (bufferOwnership() == BufferSubstring)
-            m_dataBuffer.asPtr<UStringImpl*>()->deref();
-        else {
-            ASSERT(bufferOwnership() == BufferShared);
-            m_dataBuffer.asPtr<SharedUChar*>()->deref();
-        }
-    }
-}
-
-}
index abed637af16c37ce68e58ce9dc5efa39608faff9..08f1fa5cc715b399f8e7a988907fcf72b74de103 100644 (file)
 /*
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 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
- * 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 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.
  *
  *
- * 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 UStringImpl_h
 #define UStringImpl_h
 
  */
 
 #ifndef UStringImpl_h
 #define UStringImpl_h
 
-#include <limits>
-#include <wtf/CrossThreadRefCounted.h>
-#include <wtf/OwnFastMallocPtr.h>
-#include <wtf/PossiblyNull.h>
-#include <wtf/StringHashFunctions.h>
-#include <wtf/Vector.h>
-#include <wtf/unicode/Unicode.h>
-
-namespace JSC {
-
-class IdentifierTable;
-  
-typedef CrossThreadRefCounted<OwnFastMallocPtr<UChar> > SharedUChar;
-
-class UntypedPtrAndBitfield {
-public:
-    UntypedPtrAndBitfield() {}
-
-    UntypedPtrAndBitfield(void* ptrValue, uintptr_t bitValue)
-        : m_value(reinterpret_cast<uintptr_t>(ptrValue) | bitValue)
-#ifndef NDEBUG
-        , m_leaksPtr(ptrValue)
-#endif
-    {
-        ASSERT(ptrValue == asPtr<void*>());
-        ASSERT((*this & ~s_alignmentMask) == bitValue);
-    }
-
-    template<typename T>
-    T asPtr() const { return reinterpret_cast<T>(m_value & s_alignmentMask); }
-
-    UntypedPtrAndBitfield& operator&=(uintptr_t bits)
-    {
-        m_value &= bits | s_alignmentMask;
-        return *this;
-    }
-
-    UntypedPtrAndBitfield& operator|=(uintptr_t bits)
-    {
-        m_value |= bits & ~s_alignmentMask;
-        return *this;
-    }
-
-    uintptr_t operator&(uintptr_t mask) const
-    {
-        return m_value & mask & ~s_alignmentMask;
-    }
-
-private:
-    static const uintptr_t s_alignmentMask = ~static_cast<uintptr_t>(0x7);
-    uintptr_t m_value;
-#ifndef NDEBUG
-        void* m_leaksPtr; // Only used to allow tools like leaks on OSX to detect that the memory is referenced.
-#endif
-};
-
-class UStringImpl : Noncopyable {
-public:
-    template<size_t inlineCapacity>
-    static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
-    {
-        if (unsigned length = vector.size())
-            return adoptRef(new UStringImpl(vector.releaseBuffer(), length, BufferOwned));
-        return &empty();
-    }
-
-    static PassRefPtr<UStringImpl> create(const UChar* buffer, int length)
-    {
-        UChar* newBuffer;
-        if (PassRefPtr<UStringImpl> impl = tryCreateUninitialized(length, newBuffer)) {
-            copyChars(newBuffer, buffer, length);
-            return impl;
-        }
-        return &null();
-    }
-
-    static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, int offset, int length)
-    {
-        ASSERT(rep);
-        rep->checkConsistency();
-        return adoptRef(new UStringImpl(rep->m_data + offset, length, rep->bufferOwnerString()));
-    }
-
-    static PassRefPtr<UStringImpl> create(PassRefPtr<SharedUChar> sharedBuffer, UChar* buffer, int length)
-    {
-        return adoptRef(new UStringImpl(buffer, length, sharedBuffer));
-    }
-
-    static PassRefPtr<UStringImpl> createUninitialized(unsigned length, UChar*& output)
-    {
-        if (!length) {
-            output = 0;
-            return &empty();
-        }
-
-        if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
-            CRASH();
-        UStringImpl* resultImpl = static_cast<UStringImpl*>(fastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)));
-        output = reinterpret_cast<UChar*>(resultImpl + 1);
-        return adoptRef(new(resultImpl) UStringImpl(output, length, BufferInternal));
-    }
-
-    static PassRefPtr<UStringImpl> tryCreateUninitialized(unsigned length, UChar*& output)
-    {
-        if (!length) {
-            output = 0;
-            return &empty();
-        }
-
-        if (length > ((std::numeric_limits<size_t>::max() - sizeof(UStringImpl)) / sizeof(UChar)))
-            return 0;
-        UStringImpl* resultImpl;
-        if (!tryFastMalloc(sizeof(UChar) * length + sizeof(UStringImpl)).getValue(resultImpl))
-            return 0;
-        output = reinterpret_cast<UChar*>(resultImpl + 1);
-        return adoptRef(new(resultImpl) UStringImpl(output, length, BufferInternal));
-    }
-
-    SharedUChar* sharedBuffer();
-    UChar* data() const { return m_data; }
-    int size() const { return m_length; }
-    size_t cost()
-    {
-        // For substrings, return the cost of the base string.
-        if (bufferOwnership() == BufferSubstring)
-            return m_dataBuffer.asPtr<UStringImpl*>()->cost();
-
-        if (m_dataBuffer & s_reportedCostBit)
-            return 0;
-        m_dataBuffer |= s_reportedCostBit;
-        return m_length;
-    }
-    unsigned hash() const { if (!m_hash) m_hash = computeHash(data(), m_length); return m_hash; }
-    unsigned existingHash() const { ASSERT(m_hash); return m_hash; } // fast path for Identifiers
-    void setHash(unsigned hash) { ASSERT(hash == computeHash(data(), m_length)); m_hash = hash; } // fast path for Identifiers
-    bool isIdentifier() const { return m_isIdentifier; }
-    void setIsIdentifier(bool isIdentifier) { m_isIdentifier = isIdentifier; }
-
-    UStringImpl* ref() { m_refCount += s_refCountIncrement; return this; }
-    ALWAYS_INLINE void deref() { if (!(m_refCount -= s_refCountIncrement)) delete this; }
-
-    static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
-    {
-        if (numCharacters <= s_copyCharsInlineCutOff) {
-            for (unsigned i = 0; i < numCharacters; ++i)
-                destination[i] = source[i];
-        } else
-            memcpy(destination, source, numCharacters * sizeof(UChar));
-    }
-
-    static unsigned computeHash(const UChar* s, int length) { ASSERT(length >= 0); return WTF::stringHash(s, length); }
-    static unsigned computeHash(const char* s, int length) { ASSERT(length >= 0); return WTF::stringHash(s, length); }
-    static unsigned computeHash(const char* s) { return WTF::stringHash(s); }
-
-    static UStringImpl& null() { return *s_null; }
-    static UStringImpl& empty() { return *s_empty; }
-
-    ALWAYS_INLINE void checkConsistency() const
-    {
-        // There is no recursion of substrings.
-        ASSERT(bufferOwnerString()->bufferOwnership() != BufferSubstring);
-        // Static strings cannot be put in identifier tables, because they are globally shared.
-        ASSERT(!isStatic() || !isIdentifier());
-    }
-
-private:
-    enum BufferOwnership {
-        BufferInternal,
-        BufferOwned,
-        BufferSubstring,
-        BufferShared,
-    };
-
-    // For SmallStringStorage, which allocates an array and uses an in-place new.
-    UStringImpl() { }
-
-    // Used to construct normal strings with an internal or external buffer.
-    UStringImpl(UChar* data, int length, BufferOwnership ownership)
-        : m_data(data)
-        , m_length(length)
-        , m_refCount(s_refCountIncrement)
-        , m_hash(0)
-        , m_isIdentifier(false)
-        , m_dataBuffer(0, ownership)
-    {
-        ASSERT((ownership == BufferInternal) || (ownership == BufferOwned));
-        checkConsistency();
-    }
-
-    // Used to construct static strings, which have an special refCount that can never hit zero.
-    // This means that the static string will never be destroyed, which is important because
-    // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
-    enum StaticStringConstructType { ConstructStaticString };
-    UStringImpl(UChar* data, int length, StaticStringConstructType)
-        : m_data(data)
-        , m_length(length)
-        , m_refCount(s_staticRefCountInitialValue)
-        , m_hash(0)
-        , m_isIdentifier(false)
-        , m_dataBuffer(0, BufferOwned)
-    {
-        checkConsistency();
-    }
-
-    // Used to create new strings that are a substring of an existing string.
-    UStringImpl(UChar* data, int length, PassRefPtr<UStringImpl> base)
-        : m_data(data)
-        , m_length(length)
-        , m_refCount(s_refCountIncrement)
-        , m_hash(0)
-        , m_isIdentifier(false)
-        , m_dataBuffer(base.releaseRef(), BufferSubstring)
-    {
-        // Do use static strings as a base for substrings; UntypedPtrAndBitfield assumes
-        // that all pointers will be at least 8-byte aligned, we cannot guarantee that of
-        // UStringImpls that are not heap allocated.
-        ASSERT(m_dataBuffer.asPtr<UStringImpl*>()->size());
-        ASSERT(!m_dataBuffer.asPtr<UStringImpl*>()->isStatic());
-        checkConsistency();
-    }
-
-    // Used to construct new strings sharing an existing shared buffer.
-    UStringImpl(UChar* data, int length, PassRefPtr<SharedUChar> sharedBuffer)
-        : m_data(data)
-        , m_length(length)
-        , m_refCount(s_refCountIncrement)
-        , m_hash(0)
-        , m_isIdentifier(false)
-        , m_dataBuffer(sharedBuffer.releaseRef(), BufferShared)
-    {
-        checkConsistency();
-    }
-
-    using Noncopyable::operator new;
-    void* operator new(size_t, void* inPlace) { return inPlace; }
-
-    ~UStringImpl();
-
-    // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
-    static const int s_minLengthToShare = 10;
-    static const unsigned s_copyCharsInlineCutOff = 20;
-    static const uintptr_t s_bufferOwnershipMask = 3;
-    static const uintptr_t s_reportedCostBit = 4;
-    // We initialize and increment/decrement the refCount for all normal (non-static) strings by the value 2.
-    // We initialize static strings with an odd number (specifically, 1), such that the refCount cannot reach zero.
-    static const int s_refCountIncrement = 2;
-    static const int s_staticRefCountInitialValue = 1;
-
-    UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() :  this; }
-    const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_dataBuffer.asPtr<UStringImpl*>() :  this; }
-    SharedUChar* baseSharedBuffer();
-    unsigned bufferOwnership() const { return m_dataBuffer & s_bufferOwnershipMask; }
-    bool isStatic() const { return m_refCount & 1; }
-
-    // unshared data
-    UChar* m_data;
-    int m_length;
-    unsigned m_refCount;
-    mutable unsigned m_hash : 31;
-    mutable unsigned m_isIdentifier : 1;
-    UntypedPtrAndBitfield m_dataBuffer;
-
-    JS_EXPORTDATA static UStringImpl* s_null;
-    JS_EXPORTDATA static UStringImpl* s_empty;
-
-    friend class JIT;
-    friend class SmallStringsStorage;
-    friend void initializeUString();
-};
-
-bool equal(const UStringImpl*, const UStringImpl*);
-
-}
+// FIXME: Remove this redundant name!
+#include <wtf/text/StringImpl.h>
+namespace JSC { typedef WebCore::StringImpl UStringImpl; }
 
 #endif
 
 #endif
index 3ed46451fefda6b2eb045a64ebdab8666bbe8362..9dce858704919f6575eb2970cb88fb2d069c22ea 100644 (file)
@@ -44,10 +44,13 @@ public:
         return m_ptr;
     }
     
         return m_ptr;
     }
     
-    void clear(JSCell* ptr)
+    bool clear(JSCell* ptr)
     {
     {
-        if (ptr == m_ptr)
+        if (ptr == m_ptr) {
             m_ptr = 0;
             m_ptr = 0;
+            return true;
+        }
+        return false;
     }
 
     T& operator*() const { return *get(); }
     }
 
     T& operator*() const { return *get(); }
@@ -65,11 +68,15 @@ public:
 
     WeakGCPtr& operator=(T*);
 
 
     WeakGCPtr& operator=(T*);
 
+#if !ASSERT_DISABLED
+    bool hasDeadObject() const { return !!m_ptr; }
+#endif
+
 private:
     void assign(T* ptr)
     {
 private:
     void assign(T* ptr)
     {
-        if (ptr)
-            Heap::markCell(ptr);
+        ASSERT(ptr);
+        Heap::markCell(ptr);
         m_ptr = ptr;
     }
 
         m_ptr = ptr;
     }
 
diff --git a/tests/perf/bench-allocate-nonretained.js b/tests/perf/bench-allocate-nonretained.js
new file mode 100644 (file)
index 0000000..d493416
--- /dev/null
@@ -0,0 +1,6 @@
+(function () {
+    for (var i = 0; i < 500; ++i) {
+        for (var j = 0; j < 100000; ++j)
+            var a = {};
+    }
+})();
diff --git a/tests/perf/bench-allocate-retained.js b/tests/perf/bench-allocate-retained.js
new file mode 100644 (file)
index 0000000..4e6a4bd
--- /dev/null
@@ -0,0 +1,10 @@
+(function () {
+    var a = new Array(100000);
+    for (var i = 0; i < 100000; ++i)
+        a[i] = {};
+
+    for (var i = 0; i < 500; ++i) {
+        for (var j = 0; j < 100000; ++j)
+            var b = {};
+    }
+})();
diff --git a/wrec/CharacterClass.cpp b/wrec/CharacterClass.cpp
deleted file mode 100644 (file)
index e3f12f2..0000000
+++ /dev/null
@@ -1,140 +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 "CharacterClass.h"
-
-#if ENABLE(WREC)
-
-using namespace WTF;
-
-namespace JSC { namespace WREC {
-
-const CharacterClass& CharacterClass::newline() {
-    static const UChar asciiNewlines[2] = { '\n', '\r' };
-    static const UChar unicodeNewlines[2] = { 0x2028, 0x2029 };
-    static const CharacterClass charClass = {
-        asciiNewlines, 2,
-        0, 0,
-        unicodeNewlines, 2,
-        0, 0,
-    };
-    
-    return charClass;
-}
-
-const CharacterClass& CharacterClass::digits() {
-    static const CharacterRange asciiDigitsRange[1] = { { '0', '9' } };
-    static const CharacterClass charClass = {
-        0, 0,
-        asciiDigitsRange, 1,
-        0, 0,
-        0, 0,
-    };
-    
-    return charClass;
-}
-
-const CharacterClass& CharacterClass::spaces() {
-    static const UChar asciiSpaces[1] = { ' ' };
-    static const CharacterRange asciiSpacesRange[1] = { { '\t', '\r' } };
-    static const UChar unicodeSpaces[8] = { 0x00a0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000 };
-    static const CharacterRange unicodeSpacesRange[1] = { { 0x2000, 0x200a } };
-    static const CharacterClass charClass = {
-        asciiSpaces, 1,
-        asciiSpacesRange, 1,
-        unicodeSpaces, 8,
-        unicodeSpacesRange, 1,
-    };
-    
-    return charClass;
-}
-
-const CharacterClass& CharacterClass::wordchar() {
-    static const UChar asciiWordchar[1] = { '_' };
-    static const CharacterRange asciiWordcharRange[3] = { { '0', '9' }, { 'A', 'Z' }, { 'a', 'z' } };
-    static const CharacterClass charClass = {
-        asciiWordchar, 1,
-        asciiWordcharRange, 3,
-        0, 0,
-        0, 0,
-    };
-    
-    return charClass;
-}
-
-const CharacterClass& CharacterClass::nondigits() {
-    static const CharacterRange asciiNondigitsRange[2] = { { 0, '0' - 1 }, { '9' + 1, 0x7f } };
-    static const CharacterRange unicodeNondigitsRange[1] = { { 0x0080, 0xffff } };
-    static const CharacterClass charClass = {
-        0, 0,
-        asciiNondigitsRange, 2,
-        0, 0,
-        unicodeNondigitsRange, 1,
-    };
-    
-    return charClass;
-}
-
-const CharacterClass& CharacterClass::nonspaces() {
-    static const CharacterRange asciiNonspacesRange[3] = { { 0, '\t' - 1 }, { '\r' + 1, ' ' - 1 }, { ' ' + 1, 0x7f } }; 
-    static const CharacterRange unicodeNonspacesRange[9] = {
-        { 0x0080, 0x009f },
-        { 0x00a1, 0x167f },
-        { 0x1681, 0x180d },
-        { 0x180f, 0x1fff },
-        { 0x200b, 0x2027 },
-        { 0x202a, 0x202e },
-        { 0x2030, 0x205e },
-        { 0x2060, 0x2fff },
-        { 0x3001, 0xffff }
-    }; 
-    static const CharacterClass charClass = {
-        0, 0,
-        asciiNonspacesRange, 3,
-        0, 0,
-        unicodeNonspacesRange, 9,
-    };
-    
-    return charClass;
-}
-
-const CharacterClass& CharacterClass::nonwordchar() {
-    static const UChar asciiNonwordchar[1] = { '`' };
-    static const CharacterRange asciiNonwordcharRange[4] = { { 0, '0' - 1 }, { '9' + 1, 'A' - 1 }, { 'Z' + 1, '_' - 1 }, { 'z' + 1, 0x7f } };
-    static const CharacterRange unicodeNonwordcharRange[1] = { { 0x0080, 0xffff } };
-    static const CharacterClass charClass = {
-        asciiNonwordchar, 1,
-        asciiNonwordcharRange, 4,
-        0, 0,
-        unicodeNonwordcharRange, 1,
-    };
-    
-    return charClass;
-}
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
diff --git a/wrec/CharacterClass.h b/wrec/CharacterClass.h
deleted file mode 100644 (file)
index 8a9d2fc..0000000
+++ /dev/null
@@ -1,68 +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 CharacterClass_h
-#define CharacterClass_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(WREC)
-
-#include <wtf/unicode/Unicode.h>
-
-namespace JSC { namespace WREC {
-
-    struct CharacterRange {
-        UChar begin;
-        UChar end;
-    };
-
-    struct CharacterClass {
-        static const CharacterClass& newline();
-        static const CharacterClass& digits();
-        static const CharacterClass& spaces();
-        static const CharacterClass& wordchar();
-        static const CharacterClass& nondigits();
-        static const CharacterClass& nonspaces();
-        static const CharacterClass& nonwordchar();
-
-        const UChar* matches;
-        unsigned numMatches;
-
-        const CharacterRange* ranges;
-        unsigned numRanges;
-
-        const UChar* matchesUnicode;
-        unsigned numMatchesUnicode;
-
-        const CharacterRange* rangesUnicode;
-        unsigned numRangesUnicode;
-    };
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
-
-#endif // CharacterClass_h
diff --git a/wrec/CharacterClassConstructor.cpp b/wrec/CharacterClassConstructor.cpp
deleted file mode 100644 (file)
index 06f4262..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * 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
- * 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 "CharacterClassConstructor.h"
-
-#if ENABLE(WREC)
-
-#include "pcre_internal.h"
-#include <wtf/ASCIICType.h>
-
-using namespace WTF;
-
-namespace JSC { namespace WREC {
-
-void CharacterClassConstructor::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 CharacterClassConstructor::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;
-            }
-            CharacterRange r = {lo, hi};
-            ranges.insert(i, r);
-            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.
-    CharacterRange r = {lo, hi};
-    ranges.append(r);
-}
-
-void CharacterClassConstructor::put(UChar ch)
-{
-    // Parsing a regular expression like [a-z], we start in an initial empty state:
-    //     ((m_charBuffer == -1) && !m_isPendingDash)
-    // When buffer the 'a' sice it may be (and is in this case) part of a range:
-    //     ((m_charBuffer != -1) && !m_isPendingDash)
-    // Having parsed the hyphen we then record that the dash is also pending:
-    //     ((m_charBuffer != -1) && m_isPendingDash)
-    // The next change will always take us back to the initial state - either because
-    // a complete range has been parsed (such as [a-z]), or because a flush is forced,
-    // due to an early end in the regexp ([a-]), or a character class escape being added
-    // ([a-\s]).  The fourth permutation of m_charBuffer and m_isPendingDash is not permitted.
-    ASSERT(!((m_charBuffer == -1) && m_isPendingDash));
-
-    if (m_charBuffer != -1) {
-        if (m_isPendingDash) {
-            // EXAMPLE: parsing [-a-c], the 'c' reaches this case - we have buffered a previous character and seen a hyphen, so this is a range.
-            UChar lo = m_charBuffer;
-            UChar hi = ch;
-            // Reset back to the inital state.
-            m_charBuffer = -1;
-            m_isPendingDash = false;
-            
-            // This is an error, detected lazily.  Do not proceed.
-            if (lo > hi) {
-                m_isUpsideDown = true;
-                return;
-            }
-            
-            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) {
-                UChar unicodeCurr = std::max(lo, (UChar)0x80);
-                addSortedRange(m_rangesUnicode, unicodeCurr, hi);
-                
-                if (m_isCaseInsensitive) {
-                    // we're going to scan along, updating the start of the range
-                    while (unicodeCurr <= hi) {
-                        // Spin forwards over any characters that don't have two cases.
-                        for (; jsc_pcre_ucp_othercase(unicodeCurr) == -1; ++unicodeCurr) {
-                            // if this was the last character in the range, we're done.
-                            if (unicodeCurr == hi)
-                                return;
-                        }
-                        // if we fall through to here, unicodeCurr <= hi & has another case. Get the other case.
-                        UChar rangeStart = unicodeCurr;
-                        UChar otherCurr = jsc_pcre_ucp_othercase(unicodeCurr);
-                        
-                        // If unicodeCurr is not yet hi, check the next char in the range.  If it also has another case,
-                        // and if it's other case value is one greater then the othercase value for the current last
-                        // character included in the range, we can include next into the range.
-                        while ((unicodeCurr < hi) && (jsc_pcre_ucp_othercase(unicodeCurr + 1) == (otherCurr + 1))) {
-                            // increment unicodeCurr; it points to the end of the range.
-                            // increment otherCurr, due to the check above other for next must be 1 greater than the currrent other value.
-                            ++unicodeCurr;
-                            ++otherCurr;
-                        }
-                        
-                        // otherChar is the last in the range of other case chars, calculate offset to get back to the start.
-                        addSortedRange(m_rangesUnicode, otherCurr-(unicodeCurr-rangeStart), otherCurr);
-                        
-                        // unicodeCurr has been added, move on to the next char.
-                        ++unicodeCurr;
-                    }
-                }
-            }
-        } else if (ch == '-')
-            // EXAMPLE: parsing [-a-c], the second '-' reaches this case - the hyphen is treated as potentially indicating a range.
-            m_isPendingDash = true;
-        else {
-            // EXAMPLE: Parsing [-a-c], the 'a' reaches this case - we repace the previously buffered char with the 'a'.
-            flush();
-            m_charBuffer = ch;
-        }
-    } else
-        // EXAMPLE: Parsing [-a-c], the first hyphen reaches this case - there is no buffered character
-        // (the hyphen not treated as a special character in this case, same handling for any char).
-        m_charBuffer = ch;
-}
-
-// When a character is added to the set we do not immediately add it to the arrays, in case it is actually defining a range.
-// When we have determined the character is not used in specifing a range it is added, in a sorted fashion, to the appropriate
-// array (either ascii or unicode).
-// If the pattern is case insensitive we add entries for both cases.
-void CharacterClassConstructor::flush()
-{
-    if (m_charBuffer != -1) {
-        if (m_charBuffer <= 0x7f) {
-            if (m_isCaseInsensitive && isASCIILower(m_charBuffer))
-                addSorted(m_matches, toASCIIUpper(m_charBuffer));
-            addSorted(m_matches, m_charBuffer);
-            if (m_isCaseInsensitive && isASCIIUpper(m_charBuffer))
-                addSorted(m_matches, toASCIILower(m_charBuffer));
-        } else {
-            addSorted(m_matchesUnicode, m_charBuffer);
-            if (m_isCaseInsensitive) {
-                int other = jsc_pcre_ucp_othercase(m_charBuffer);
-                if (other != -1)
-                    addSorted(m_matchesUnicode, other);
-            }
-        }
-        m_charBuffer = -1;
-    }
-    
-    if (m_isPendingDash) {
-        addSorted(m_matches, '-');
-        m_isPendingDash = false;
-    }
-}
-
-void CharacterClassConstructor::append(const CharacterClass& other)
-{
-    // [x-\s] will add, 'x', '-', and all unicode spaces to new class (same as [x\s-]).
-    // Need to check the spec, really, but think this matches PCRE behaviour.
-    flush();
-    
-    if (other.numMatches) {
-        for (size_t i = 0; i < other.numMatches; ++i)
-            addSorted(m_matches, other.matches[i]);
-    }
-    if (other.numRanges) {
-        for (size_t i = 0; i < other.numRanges; ++i)
-            addSortedRange(m_ranges, other.ranges[i].begin, other.ranges[i].end);
-    }
-    if (other.numMatchesUnicode) {
-        for (size_t i = 0; i < other.numMatchesUnicode; ++i)
-            addSorted(m_matchesUnicode, other.matchesUnicode[i]);
-    }
-    if (other.numRangesUnicode) {
-        for (size_t i = 0; i < other.numRangesUnicode; ++i)
-            addSortedRange(m_rangesUnicode, other.rangesUnicode[i].begin, other.rangesUnicode[i].end);
-    }
-}
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
diff --git a/wrec/CharacterClassConstructor.h b/wrec/CharacterClassConstructor.h
deleted file mode 100644 (file)
index 581733d..0000000
+++ /dev/null
@@ -1,99 +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 CharacterClassConstructor_h
-#define CharacterClassConstructor_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(WREC)
-
-#include "CharacterClass.h"
-#include <wtf/AlwaysInline.h>
-#include <wtf/Vector.h>
-#include <wtf/unicode/Unicode.h>
-
-namespace JSC { namespace WREC {
-
-    class CharacterClassConstructor {
-    public:
-        CharacterClassConstructor(bool isCaseInsensitive)
-            : m_charBuffer(-1)
-            , m_isPendingDash(false)
-            , m_isCaseInsensitive(isCaseInsensitive)
-            , m_isUpsideDown(false)
-        {
-        }
-
-        void flush();
-        
-        // We need to flush prior to an escaped hyphen to prevent it as being treated as indicating
-        // a range, e.g. [a\-c] we flush prior to adding the hyphen so that this is not treated as
-        // [a-c].  However, we do not want to flush if we have already seen a non escaped hyphen -
-        // e.g. [+-\-] should be treated the same as [+--], producing a range that will also match
-        // a comma.
-        void flushBeforeEscapedHyphen()
-        {
-            if (!m_isPendingDash)
-                flush();
-        }
-        
-        void put(UChar ch);
-        void append(const CharacterClass& other);
-
-        bool isUpsideDown() { return m_isUpsideDown; }
-
-        ALWAYS_INLINE CharacterClass charClass()
-        {
-            CharacterClass newCharClass = {
-                m_matches.begin(), m_matches.size(),
-                m_ranges.begin(), m_ranges.size(),
-                m_matchesUnicode.begin(), m_matchesUnicode.size(),
-                m_rangesUnicode.begin(), m_rangesUnicode.size(),
-            };
-
-            return newCharClass;
-        }
-
-    private:
-        void addSorted(Vector<UChar>& matches, UChar ch);
-        void addSortedRange(Vector<CharacterRange>& ranges, UChar lo, UChar hi);
-
-        int m_charBuffer;
-        bool m_isPendingDash;
-        bool m_isCaseInsensitive;
-        bool m_isUpsideDown;
-
-        Vector<UChar> m_matches;
-        Vector<CharacterRange> m_ranges;
-        Vector<UChar> m_matchesUnicode;
-        Vector<CharacterRange> m_rangesUnicode;
-    };
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
-
-#endif // CharacterClassConstructor_h
diff --git a/wrec/Escapes.h b/wrec/Escapes.h
deleted file mode 100644 (file)
index 16c1d6f..0000000
+++ /dev/null
@@ -1,150 +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 Escapes_h
-#define Escapes_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(WREC)
-
-#include <wtf/Assertions.h>
-
-namespace JSC { namespace WREC {
-
-    class CharacterClass;
-
-    class Escape {
-    public:
-        enum Type {
-            PatternCharacter,
-            CharacterClass,
-            Backreference,
-            WordBoundaryAssertion,
-            Error,
-        };
-        
-        Escape(Type type)
-            : m_type(type)
-        {
-        }
-
-        Type type() const { return m_type; }
-
-    private:
-        Type m_type;
-        
-    protected:
-        // Used by subclasses to store data.
-        union {
-            int i;
-            const WREC::CharacterClass* c;
-        } m_u;
-        bool m_invert;
-    };
-
-    class PatternCharacterEscape : public Escape {
-    public:
-        static const PatternCharacterEscape& cast(const Escape& escape)
-        {
-            ASSERT(escape.type() == PatternCharacter);
-            return static_cast<const PatternCharacterEscape&>(escape);
-        }
-        
-        PatternCharacterEscape(int character)
-            : Escape(PatternCharacter)
-        {
-            m_u.i = character;
-        }
-        
-        operator Escape() const { return *this; }
-        
-        int character() const { return m_u.i; }
-    };
-
-    class CharacterClassEscape : public Escape {
-    public:
-        static const CharacterClassEscape& cast(const Escape& escape)
-        {
-            ASSERT(escape.type() == CharacterClass);
-            return static_cast<const CharacterClassEscape&>(escape);
-        }
-        
-        CharacterClassEscape(const WREC::CharacterClass& characterClass, bool invert)
-            : Escape(CharacterClass)
-        {
-            m_u.c = &characterClass;
-            m_invert = invert;
-        }
-        
-        operator Escape() { return *this; }
-        
-        const WREC::CharacterClass& characterClass() const { return *m_u.c; }
-        bool invert() const { return m_invert; }
-    };
-
-    class BackreferenceEscape : public Escape {
-    public:
-        static const BackreferenceEscape& cast(const Escape& escape)
-        {
-            ASSERT(escape.type() == Backreference);
-            return static_cast<const BackreferenceEscape&>(escape);
-        }
-        
-        BackreferenceEscape(int subpatternId)
-            : Escape(Backreference)
-        {
-            m_u.i = subpatternId;
-        }
-        
-        operator Escape() const { return *this; }
-        
-        int subpatternId() const { return m_u.i; }
-    };
-
-    class WordBoundaryAssertionEscape : public Escape {
-    public:
-        static const WordBoundaryAssertionEscape& cast(const Escape& escape)
-        {
-            ASSERT(escape.type() == WordBoundaryAssertion);
-            return static_cast<const WordBoundaryAssertionEscape&>(escape);
-        }
-        
-        WordBoundaryAssertionEscape(bool invert)
-            : Escape(WordBoundaryAssertion)
-        {
-            m_invert = invert;
-        }
-        
-        operator Escape() const { return *this; }
-        
-        bool invert() const { return m_invert; }
-    };
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
-
-#endif // Escapes_h
diff --git a/wrec/Quantifier.h b/wrec/Quantifier.h
deleted file mode 100644 (file)
index 3da74cd..0000000
+++ /dev/null
@@ -1,66 +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 Quantifier_h
-#define Quantifier_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(WREC)
-
-#include <wtf/Assertions.h>
-#include <limits.h>
-
-namespace JSC { namespace WREC {
-
-    struct Quantifier {
-        enum Type {
-            None,
-            Greedy,
-            NonGreedy,
-            Error,
-        };
-
-        Quantifier(Type type = None, unsigned min = 0, unsigned max = Infinity)
-            : type(type)
-            , min(min)
-            , max(max)
-        {
-            ASSERT(min <= max);
-        }
-
-        Type type;
-
-        unsigned min;
-        unsigned max;
-
-        static const unsigned Infinity = UINT_MAX;
-    };
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
-
-#endif // Quantifier_h
diff --git a/wrec/WREC.cpp b/wrec/WREC.cpp
deleted file mode 100644 (file)
index 145a1ce..0000000
+++ /dev/null
@@ -1,86 +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 "WREC.h"
-
-#if ENABLE(WREC)
-
-#include "CharacterClassConstructor.h"
-#include "Interpreter.h"
-#include "JSGlobalObject.h"
-#include "RegisterFile.h"
-#include "WRECFunctors.h"
-#include "WRECParser.h"
-#include "pcre_internal.h"
-
-using namespace WTF;
-
-namespace JSC { namespace WREC {
-
-CompiledRegExp Generator::compileRegExp(JSGlobalData* globalData, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, RefPtr<ExecutablePool>& pool, bool ignoreCase, bool multiline)
-{
-    if (pattern.size() > MAX_PATTERN_SIZE) {
-        *error_ptr = "regular expression too large";
-        return 0;
-    }
-
-    Parser parser(pattern, ignoreCase, multiline);
-    Generator& generator = parser.generator();
-    MacroAssembler::JumpList failures;
-    MacroAssembler::Jump endOfInput;
-
-    generator.generateEnter();
-    generator.generateSaveIndex();
-
-    Label beginPattern(&generator);
-    parser.parsePattern(failures);
-    generator.generateReturnSuccess();
-
-    failures.link(&generator);
-    generator.generateIncrementIndex(&endOfInput);
-    parser.parsePattern(failures);
-    generator.generateReturnSuccess();
-
-    failures.link(&generator);
-    generator.generateIncrementIndex();
-    generator.generateJumpIfNotEndOfInput(beginPattern);
-    
-    endOfInput.link(&generator);
-    generator.generateReturnFailure();
-
-    if (parser.error()) {
-        *error_ptr = parser.syntaxError(); // NULL in the case of patterns that WREC doesn't support yet.
-        return 0;
-    }
-
-    *numSubpatterns_ptr = parser.numSubpatterns();
-    pool = globalData->executableAllocator.poolForSize(generator.size());
-    return reinterpret_cast<CompiledRegExp>(generator.copyCode(pool.get()));
-}
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
diff --git a/wrec/WREC.h b/wrec/WREC.h
deleted file mode 100644 (file)
index 13324e7..0000000
+++ /dev/null
@@ -1,54 +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 WREC_h
-#define WREC_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(WREC)
-
-#include <wtf/unicode/Unicode.h>
-
-#if COMPILER(GCC) && CPU(X86)
-#define WREC_CALL __attribute__ ((regparm (3)))
-#else
-#define WREC_CALL
-#endif
-
-namespace JSC {
-    class Interpreter;
-    class UString;
-}
-
-namespace JSC { namespace WREC {
-
-    typedef int (*CompiledRegExp)(const UChar* input, unsigned start, unsigned length, int* output) WREC_CALL;
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
-
-#endif // WREC_h
diff --git a/wrec/WRECFunctors.cpp b/wrec/WRECFunctors.cpp
deleted file mode 100644 (file)
index 5f1674e..0000000
+++ /dev/null
@@ -1,80 +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 "WRECFunctors.h"
-
-#if ENABLE(WREC)
-
-#include "WRECGenerator.h"
-
-using namespace WTF;
-
-namespace JSC { namespace WREC {
-
-void GeneratePatternCharacterFunctor::generateAtom(Generator* generator, Generator::JumpList& failures)
-{
-    generator->generatePatternCharacter(failures, m_ch);
-}
-
-void GeneratePatternCharacterFunctor::backtrack(Generator* generator)
-{
-    generator->generateBacktrack1();
-}
-
-void GenerateCharacterClassFunctor::generateAtom(Generator* generator, Generator::JumpList& failures)
-{
-    generator->generateCharacterClass(failures, *m_charClass, m_invert);
-}
-
-void GenerateCharacterClassFunctor::backtrack(Generator* generator)
-{
-    generator->generateBacktrack1();
-}
-
-void GenerateBackreferenceFunctor::generateAtom(Generator* generator, Generator::JumpList& failures)
-{
-    generator->generateBackreference(failures, m_subpatternId);
-}
-
-void GenerateBackreferenceFunctor::backtrack(Generator* generator)
-{
-    generator->generateBacktrackBackreference(m_subpatternId);
-}
-
-void GenerateParenthesesNonGreedyFunctor::generateAtom(Generator* generator, Generator::JumpList& failures)
-{
-    generator->generateParenthesesNonGreedy(failures, m_start, m_success, m_fail);
-}
-
-void GenerateParenthesesNonGreedyFunctor::backtrack(Generator*)
-{
-    // FIXME: do something about this.
-    CRASH();
-}
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
diff --git a/wrec/WRECFunctors.h b/wrec/WRECFunctors.h
deleted file mode 100644 (file)
index 610ce55..0000000
+++ /dev/null
@@ -1,109 +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 <wtf/Platform.h>
-
-#if ENABLE(WREC)
-
-#include "WRECGenerator.h"
-#include <wtf/unicode/Unicode.h>
-
-namespace JSC { namespace WREC {
-
-    struct CharacterClass;
-
-    class GenerateAtomFunctor {
-    public:
-        virtual ~GenerateAtomFunctor() {}
-
-        virtual void generateAtom(Generator*, Generator::JumpList&) = 0;
-        virtual void backtrack(Generator*) = 0;
-    };
-
-    class GeneratePatternCharacterFunctor : public GenerateAtomFunctor {
-    public:
-        GeneratePatternCharacterFunctor(const UChar ch)
-            : m_ch(ch)
-        {
-        }
-
-        virtual void generateAtom(Generator*, Generator::JumpList&);
-        virtual void backtrack(Generator*);
-
-    private:
-        const UChar m_ch;
-    };
-
-    class GenerateCharacterClassFunctor : public GenerateAtomFunctor {
-    public:
-        GenerateCharacterClassFunctor(const CharacterClass* charClass, bool invert)
-            : m_charClass(charClass)
-            , m_invert(invert)
-        {
-        }
-
-        virtual void generateAtom(Generator*, Generator::JumpList&);
-        virtual void backtrack(Generator*);
-
-    private:
-        const CharacterClass* m_charClass;
-        bool m_invert;
-    };
-
-    class GenerateBackreferenceFunctor : public GenerateAtomFunctor {
-    public:
-        GenerateBackreferenceFunctor(unsigned subpatternId)
-            : m_subpatternId(subpatternId)
-        {
-        }
-
-        virtual void generateAtom(Generator*, Generator::JumpList&);
-        virtual void backtrack(Generator*);
-
-    private:
-        unsigned m_subpatternId;
-    };
-
-    class GenerateParenthesesNonGreedyFunctor : public GenerateAtomFunctor {
-    public:
-        GenerateParenthesesNonGreedyFunctor(Generator::Label start, Generator::Jump success, Generator::Jump fail)
-            : m_start(start)
-            , m_success(success)
-            , m_fail(fail)
-        {
-        }
-
-        virtual void generateAtom(Generator*, Generator::JumpList&);
-        virtual void backtrack(Generator*);
-
-    private:
-        Generator::Label m_start;
-        Generator::Jump m_success;
-        Generator::Jump m_fail;
-    };
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
diff --git a/wrec/WRECGenerator.cpp b/wrec/WRECGenerator.cpp
deleted file mode 100644 (file)
index 7105984..0000000
+++ /dev/null
@@ -1,653 +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 "WREC.h"
-
-#if ENABLE(WREC)
-
-#include "CharacterClassConstructor.h"
-#include "Interpreter.h"
-#include "WRECFunctors.h"
-#include "WRECParser.h"
-#include "pcre_internal.h"
-
-using namespace WTF;
-
-namespace JSC { namespace WREC {
-
-void Generator::generateEnter()
-{
-#if CPU(X86)
-    // On x86 edi & esi are callee preserved registers.
-    push(X86Registers::edi);
-    push(X86Registers::esi);
-    
-#if COMPILER(MSVC)
-    // Move the arguments into registers.
-    peek(input, 3);
-    peek(index, 4);
-    peek(length, 5);
-    peek(output, 6);
-#else
-    // On gcc the function is regparm(3), so the input, index, and length registers
-    // (eax, edx, and ecx respectively) already contain the appropriate values.
-    // Just load the fourth argument (output) into edi
-    peek(output, 3);
-#endif
-#endif
-}
-
-void Generator::generateReturnSuccess()
-{
-    ASSERT(returnRegister != index);
-    ASSERT(returnRegister != output);
-
-    // Set return value.
-    pop(returnRegister); // match begin
-    store32(returnRegister, output);
-    store32(index, Address(output, 4)); // match end
-    
-    // Restore callee save registers.
-#if CPU(X86)
-    pop(X86Registers::esi);
-    pop(X86Registers::edi);
-#endif
-    ret();
-}
-
-void Generator::generateSaveIndex()
-{
-    push(index);
-}
-
-void Generator::generateIncrementIndex(Jump* failure)
-{
-    peek(index);
-    if (failure)
-        *failure = branch32(Equal, length, index);
-    add32(Imm32(1), index);
-    poke(index);
-}
-
-void Generator::generateLoadCharacter(JumpList& failures)
-{
-    failures.append(branch32(Equal, length, index));
-    load16(BaseIndex(input, index, TimesTwo), character);
-}
-
-// For the sake of end-of-line assertions, we treat one-past-the-end as if it
-// were part of the input string.
-void Generator::generateJumpIfNotEndOfInput(Label target)
-{
-    branch32(LessThanOrEqual, index, length, target);
-}
-
-void Generator::generateReturnFailure()
-{
-    pop();
-    move(Imm32(-1), returnRegister);
-
-#if CPU(X86)
-    pop(X86Registers::esi);
-    pop(X86Registers::edi);
-#endif
-    ret();
-}
-
-void Generator::generateBacktrack1()
-{
-    sub32(Imm32(1), index);
-}
-
-void Generator::generateBacktrackBackreference(unsigned subpatternId)
-{
-    sub32(Address(output, (2 * subpatternId + 1) * sizeof(int)), index);
-    add32(Address(output, (2 * subpatternId) * sizeof(int)), index);
-}
-
-void Generator::generateBackreferenceQuantifier(JumpList& failures, Quantifier::Type quantifierType, unsigned subpatternId, unsigned min, unsigned max)
-{
-    GenerateBackreferenceFunctor functor(subpatternId);
-
-    load32(Address(output, (2 * subpatternId) * 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)
-        generateGreedyQuantifier(failures, functor, min, max);
-    else
-        generateNonGreedyQuantifier(failures, functor, min, max);
-
-    skipIfEmpty.link(this);
-}
-
-void Generator::generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max)
-{
-    JumpList atomFailedList;
-    JumpList alternativeFailedList;
-
-    // (0) Setup: Save, then init repeatCount.
-    push(repeatCount);
-    move(Imm32(0), repeatCount);
-    Jump start = jump();
-
-    // (4) Quantifier failed: No more atom reading possible.
-    Label quantifierFailed(this);
-    pop(repeatCount);
-    failures.append(jump()); 
-
-    // (3) Alternative failed: If we can, read another atom, then fall through to (2) to try again.
-    Label alternativeFailed(this);
-    pop(index);
-    if (max != Quantifier::Infinity)
-        branch32(Equal, repeatCount, Imm32(max), quantifierFailed);
-
-    // (1) Read an atom.
-    if (min)
-        start.link(this);
-    Label readAtom(this);
-    functor.generateAtom(this, atomFailedList);
-    atomFailedList.linkTo(quantifierFailed, this);
-    add32(Imm32(1), repeatCount);
-    
-    // (2) Keep reading if we're under the minimum.
-    if (min > 1)
-        branch32(LessThan, repeatCount, Imm32(min), readAtom);
-
-    // (3) Test the rest of the alternative.
-    if (!min)
-        start.link(this);
-    push(index);
-    m_parser.parseAlternative(alternativeFailedList);
-    alternativeFailedList.linkTo(alternativeFailed, this);
-
-    pop();
-    pop(repeatCount);
-}
-
-void Generator::generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max)
-{
-    if (!max)
-        return;
-
-    JumpList doneReadingAtomsList;
-    JumpList alternativeFailedList;
-
-    // (0) Setup: Save, then init repeatCount.
-    push(repeatCount);
-    move(Imm32(0), repeatCount);
-
-    // (1) Greedily read as many copies of the atom as possible, then jump to (2).
-    Label readAtom(this);
-    functor.generateAtom(this, doneReadingAtomsList);
-    add32(Imm32(1), repeatCount);
-    if (max == Quantifier::Infinity)
-        jump(readAtom);
-    else if (max == 1)
-        doneReadingAtomsList.append(jump());
-    else {
-        branch32(NotEqual, repeatCount, Imm32(max), readAtom);
-        doneReadingAtomsList.append(jump());
-    }
-
-    // (5) Quantifier failed: No more backtracking possible.
-    Label quantifierFailed(this);
-    pop(repeatCount);
-    failures.append(jump()); 
-
-    // (4) Alternative failed: Backtrack, then fall through to (2) to try again.
-    Label alternativeFailed(this);
-    pop(index);
-    functor.backtrack(this);
-    sub32(Imm32(1), repeatCount);
-
-    // (2) Verify that we have enough atoms.
-    doneReadingAtomsList.link(this);
-    branch32(LessThan, repeatCount, Imm32(min), quantifierFailed);
-
-    // (3) Test the rest of the alternative.
-    push(index);
-    m_parser.parseAlternative(alternativeFailedList);
-    alternativeFailedList.linkTo(alternativeFailed, this);
-
-    pop();
-    pop(repeatCount);
-}
-
-void Generator::generatePatternCharacterSequence(JumpList& failures, int* sequence, size_t count)
-{
-    for (size_t i = 0; i < count;) {
-        if (i < count - 1) {
-            if (generatePatternCharacterPair(failures, sequence[i], sequence[i + 1])) {
-                i += 2;
-                continue;
-            }
-        }
-
-        generatePatternCharacter(failures, sequence[i]);
-        ++i;
-    }
-}
-
-bool Generator::generatePatternCharacterPair(JumpList& failures, int ch1, int ch2)
-{
-    if (m_parser.ignoreCase()) {
-        // Non-trivial case folding requires more than one test, so we can't
-        // test as a pair with an adjacent character.
-        if (!isASCII(ch1) && Unicode::toLower(ch1) != Unicode::toUpper(ch1))
-            return false;
-        if (!isASCII(ch2) && Unicode::toLower(ch2) != Unicode::toUpper(ch2))
-            return false;
-    }
-
-    // Optimistically consume 2 characters.
-    add32(Imm32(2), index);
-    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);
-
-    if (m_parser.ignoreCase()) {
-        // Convert ASCII alphabet characters to upper case before testing for
-        // equality. (ASCII non-alphabet characters don't require upper-casing
-        // because they have no uppercase equivalents. Unicode characters don't
-        // require upper-casing because we only handle Unicode characters whose
-        // upper and lower cases are equal.)
-        int ch1Mask = 0;
-        if (isASCIIAlpha(ch1)) {
-            ch1 |= 32;
-            ch1Mask = 32;
-        }
-
-        int ch2Mask = 0;
-        if (isASCIIAlpha(ch2)) {
-            ch2 |= 32;
-            ch2Mask = 32;
-        }
-
-        int mask = ch1Mask | (ch2Mask << 16);
-        if (mask)
-            or32(Imm32(mask), character);
-    }
-    int pair = ch1 | (ch2 << 16);
-
-    failures.append(branch32(NotEqual, character, Imm32(pair)));
-    return true;
-}
-
-void Generator::generatePatternCharacter(JumpList& failures, int ch)
-{
-    generateLoadCharacter(failures);
-
-    // used for unicode case insensitive
-    bool hasUpper = false;
-    Jump isUpper;
-    
-    // if case insensitive match
-    if (m_parser.ignoreCase()) {
-        UChar lower, upper;
-        
-        // check for ascii case sensitive characters
-        if (isASCIIAlpha(ch)) {
-            or32(Imm32(32), character);
-            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 = branch32(Equal, character, Imm32(upper));
-            hasUpper = true;
-            ch = lower;
-        }
-    }
-    
-    // checks for ch, or lower case version of ch, if insensitive
-    failures.append(branch32(NotEqual, character, Imm32((unsigned short)ch)));
-
-    if (m_parser.ignoreCase() && hasUpper) {
-        // for unicode case insensitive matches, branch here if upper matches.
-        isUpper.link(this);
-    }
-    
-    // on success consume the char
-    add32(Imm32(1), index);
-}
-
-void Generator::generateCharacterClassInvertedRange(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)
-                generateCharacterClassInvertedRange(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));
-
-            generateCharacterClassInvertedRange(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 Generator::generateCharacterClassInverted(JumpList& matchDest, const CharacterClass& charClass)
-{
-    Jump unicodeFail;
-    if (charClass.numMatchesUnicode || charClass.numRangesUnicode) {
-        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(branch32(Equal, character, Imm32(ch)));
-            }
-        }
-        
-        if (charClass.numRangesUnicode) {
-            for (unsigned i = 0; i < charClass.numRangesUnicode; ++i) {
-                UChar lo = charClass.rangesUnicode[i].begin;
-                UChar hi = charClass.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.numRanges) {
-        unsigned matchIndex = 0;
-        JumpList failures; 
-        generateCharacterClassInvertedRange(failures, matchDest, charClass.ranges, charClass.numRanges, &matchIndex, charClass.matches, charClass.numMatches);
-        while (matchIndex < charClass.numMatches)
-            matchDest.append(branch32(Equal, character, Imm32((unsigned short)charClass.matches[matchIndex++])));
-
-        failures.link(this);
-    } else if (charClass.numMatches) {
-        // optimization: gather 'a','A' etc back together, can mask & test once.
-        Vector<char> matchesAZaz;
-
-        for (unsigned i = 0; i < charClass.numMatches; ++i) {
-            char ch = charClass.matches[i];
-            if (m_parser.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.numMatchesUnicode || charClass.numRangesUnicode)
-        unicodeFail.link(this);
-}
-
-void Generator::generateCharacterClass(JumpList& failures, const CharacterClass& charClass, bool invert)
-{
-    generateLoadCharacter(failures);
-
-    if (invert)
-        generateCharacterClassInverted(failures, charClass);
-    else {
-        JumpList successes;
-        generateCharacterClassInverted(successes, charClass);
-        failures.append(jump());
-        successes.link(this);
-    }
-    
-    add32(Imm32(1), index);
-}
-
-void Generator::generateParenthesesAssertion(JumpList& failures)
-{
-    JumpList disjunctionFailed;
-
-    push(index);
-    m_parser.parseDisjunction(disjunctionFailed);
-    Jump success = jump();
-
-    disjunctionFailed.link(this);
-    pop(index);
-    failures.append(jump());
-
-    success.link(this);
-    pop(index);
-}
-
-void Generator::generateParenthesesInvertedAssertion(JumpList& failures)
-{
-    JumpList disjunctionFailed;
-
-    push(index);
-    m_parser.parseDisjunction(disjunctionFailed);
-
-    // If the disjunction succeeded, the inverted assertion failed.
-    pop(index);
-    failures.append(jump());
-
-    // If the disjunction failed, the inverted assertion succeeded.
-    disjunctionFailed.link(this);
-    pop(index);
-}
-
-void Generator::generateParenthesesNonGreedy(JumpList& failures, Label start, Jump success, Jump fail)
-{
-    jump(start);
-    success.link(this);
-    failures.append(fail);
-}
-
-Generator::Jump Generator::generateParenthesesResetTrampoline(JumpList& newFailures, unsigned subpatternIdBefore, unsigned subpatternIdAfter)
-{
-    Jump skip = jump();
-    newFailures.link(this);
-    for (unsigned i = subpatternIdBefore + 1; i <= subpatternIdAfter; ++i) {
-        store32(Imm32(-1), Address(output, (2 * i) * sizeof(int)));
-        store32(Imm32(-1), Address(output, (2 * i + 1) * sizeof(int)));
-    }
-    
-    Jump newFailJump = jump();
-    skip.link(this);
-    
-    return newFailJump;
-}
-
-void Generator::generateAssertionBOL(JumpList& failures)
-{
-    if (m_parser.multiline()) {
-        JumpList previousIsNewline;
-
-        // begin of input == success
-        previousIsNewline.append(branch32(Equal, index, Imm32(0)));
-
-        // now check prev char against newline characters.
-        load16(BaseIndex(input, index, TimesTwo, -2), character);
-        generateCharacterClassInverted(previousIsNewline, CharacterClass::newline());
-
-        failures.append(jump());
-
-        previousIsNewline.link(this);
-    } else
-        failures.append(branch32(NotEqual, index, Imm32(0)));
-}
-
-void Generator::generateAssertionEOL(JumpList& failures)
-{
-    if (m_parser.multiline()) {
-        JumpList nextIsNewline;
-
-        generateLoadCharacter(nextIsNewline); // end of input == success
-        generateCharacterClassInverted(nextIsNewline, CharacterClass::newline());
-        failures.append(jump());
-        nextIsNewline.link(this);
-    } else {
-        failures.append(branch32(NotEqual, length, index));
-    }
-}
-
-void Generator::generateAssertionWordBoundary(JumpList& failures, bool invert)
-{
-    JumpList wordBoundary;
-    JumpList notWordBoundary;
-
-    // (1) Check if the previous value was a word char
-
-    // (1.1) check for begin of input
-    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;
-    generateCharacterClassInverted(previousIsWord, CharacterClass::wordchar());
-    // (1.3) if we get here, previous is not a word char
-    atBegin.link(this);
-
-    // (2) Handle situation where previous was NOT a \w
-
-    generateLoadCharacter(notWordBoundary);
-    generateCharacterClassInverted(wordBoundary, CharacterClass::wordchar());
-    // (2.1) If we get here, neither chars are word chars
-    notWordBoundary.append(jump());
-
-    // (3) Handle situation where previous was a \w
-
-    // (3.0) link success in first match to here
-    previousIsWord.link(this);
-    generateLoadCharacter(wordBoundary);
-    generateCharacterClassInverted(notWordBoundary, CharacterClass::wordchar());
-    // (3.1) If we get here, this is an end of a word, within the input.
-    
-    // (4) Link everything up
-    
-    if (invert) {
-        // handle the fall through case
-        wordBoundary.append(jump());
-    
-        // looking for non word boundaries, so link boundary fails to here.
-        notWordBoundary.link(this);
-
-        failures.append(wordBoundary);
-    } else {
-        // looking for word boundaries, so link successes here.
-        wordBoundary.link(this);
-        
-        failures.append(notWordBoundary);
-    }
-}
-
-void Generator::generateBackreference(JumpList& failures, unsigned subpatternId)
-{
-    push(index);
-    push(repeatCount);
-
-    // get the start pos of the backref into repeatCount (multipurpose!)
-    load32(Address(output, (2 * subpatternId) * sizeof(int)), repeatCount);
-
-    Jump skipIncrement = jump();
-    Label topOfLoop(this);
-
-    add32(Imm32(1), index);
-    add32(Imm32(1), repeatCount);
-    skipIncrement.link(this);
-
-    // check if we're at the end of backref (if we are, success!)
-    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 = branch32(Equal, length, index);
-
-    branch16(Equal, BaseIndex(input, index, TimesTwo), character, topOfLoop);
-
-    endOfInput.link(this);
-
-    // Failure
-    pop(repeatCount);
-    pop(index);
-    failures.append(jump());
-
-    // Success
-    endOfBackRef.link(this);
-    pop(repeatCount);
-    pop();
-}
-
-void Generator::terminateAlternative(JumpList& successes, JumpList& failures)
-{
-    successes.append(jump());
-    
-    failures.link(this);
-    peek(index);
-}
-
-void Generator::terminateDisjunction(JumpList& successes)
-{
-    successes.link(this);
-}
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
diff --git a/wrec/WRECGenerator.h b/wrec/WRECGenerator.h
deleted file mode 100644 (file)
index d707a6e..0000000
+++ /dev/null
@@ -1,128 +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 WRECGenerator_h
-#define WRECGenerator_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(WREC)
-
-#include "Quantifier.h"
-#include "MacroAssembler.h"
-#include <wtf/ASCIICType.h>
-#include <wtf/unicode/Unicode.h>
-#include "WREC.h"
-
-namespace JSC { 
-
-    class JSGlobalData;
-
-    namespace WREC {
-
-    class CharacterRange;
-    class GenerateAtomFunctor;
-    class Parser;
-    struct CharacterClass;
-
-    class Generator : private MacroAssembler {
-    public:
-        using MacroAssembler::Jump;
-        using MacroAssembler::JumpList;
-        using MacroAssembler::Label;
-
-        enum ParenthesesType { Capturing, NonCapturing, Assertion, InvertedAssertion, Error };
-
-        static CompiledRegExp compileRegExp(JSGlobalData*, const UString& pattern, unsigned* numSubpatterns_ptr, const char** error_ptr, RefPtr<ExecutablePool>& pool, bool ignoreCase = false, bool multiline = false);
-    
-        Generator(Parser& parser)
-            : m_parser(parser)
-        {
-        }
-
-#if CPU(X86)
-        static const RegisterID input = X86Registers::eax;
-        static const RegisterID index = X86Registers::edx;
-        static const RegisterID length = X86Registers::ecx;
-        static const RegisterID output = X86Registers::edi;
-
-        static const RegisterID character = X86Registers::esi;
-        static const RegisterID repeatCount = X86Registers::ebx; // How many times the current atom repeats in the current match.
-
-        static const RegisterID returnRegister = X86Registers::eax;
-#endif
-#if CPU(X86_64)
-        static const RegisterID input = X86Registers::edi;
-        static const RegisterID index = X86Registers::esi;
-        static const RegisterID length = X86Registers::edx;
-        static const RegisterID output = X86Registers::ecx;
-
-        static const RegisterID character = X86Registers::eax;
-        static const RegisterID repeatCount = X86Registers::ebx; // How many times the current atom repeats in the current match.
-
-        static const RegisterID returnRegister = X86Registers::eax;
-#endif
-
-        void generateEnter();
-        void generateSaveIndex();
-        void generateIncrementIndex(Jump* failure = 0);
-        void generateLoadCharacter(JumpList& failures);
-        void generateJumpIfNotEndOfInput(Label);
-        void generateReturnSuccess();
-        void generateReturnFailure();
-
-        void generateGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max);
-        void generateNonGreedyQuantifier(JumpList& failures, GenerateAtomFunctor& functor, unsigned min, unsigned max);
-        void generateBacktrack1();
-        void generateBacktrackBackreference(unsigned subpatternId);
-        void generateCharacterClass(JumpList& failures, const CharacterClass& charClass, bool invert);
-        void generateCharacterClassInverted(JumpList& failures, const CharacterClass& charClass);
-        void generateCharacterClassInvertedRange(JumpList& failures, JumpList& matchDest, const CharacterRange* ranges, unsigned count, unsigned* matchIndex, const UChar* matches, unsigned matchCount);
-        void generatePatternCharacter(JumpList& failures, int ch);
-        void generatePatternCharacterSequence(JumpList& failures, int* sequence, size_t count);
-        void generateAssertionWordBoundary(JumpList& failures, bool invert);
-        void generateAssertionBOL(JumpList& failures);
-        void generateAssertionEOL(JumpList& failures);
-        void generateBackreference(JumpList& failures, unsigned subpatternID);
-        void generateBackreferenceQuantifier(JumpList& failures, Quantifier::Type quantifierType, unsigned subpatternId, unsigned min, unsigned max);
-        void generateParenthesesAssertion(JumpList& failures);
-        void generateParenthesesInvertedAssertion(JumpList& failures);
-        Jump generateParenthesesResetTrampoline(JumpList& newFailures, unsigned subpatternIdBefore, unsigned subpatternIdAfter);
-        void generateParenthesesNonGreedy(JumpList& failures, Label start, Jump success, Jump fail);
-
-        void terminateAlternative(JumpList& successes, JumpList& failures);
-        void terminateDisjunction(JumpList& successes);
-
-    private:
-        bool generatePatternCharacterPair(JumpList& failures, int ch1, int ch2);
-
-        Parser& m_parser;
-    };
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
-
-#endif // WRECGenerator_h
diff --git a/wrec/WRECParser.cpp b/wrec/WRECParser.cpp
deleted file mode 100644 (file)
index 1709bf9..0000000
+++ /dev/null
@@ -1,643 +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 "WRECParser.h"
-
-#if ENABLE(WREC)
-
-#include "CharacterClassConstructor.h"
-#include "WRECFunctors.h"
-
-using namespace WTF;
-
-namespace JSC { namespace WREC {
-
-// These error messages match the error messages used by PCRE.
-const char* Parser::QuantifierOutOfOrder = "numbers out of order in {} quantifier";
-const char* Parser::QuantifierWithoutAtom = "nothing to repeat";
-const char* Parser::ParenthesesUnmatched = "unmatched parentheses";
-const char* Parser::ParenthesesTypeInvalid = "unrecognized character after (?";
-const char* Parser::ParenthesesNotSupported = ""; // Not a user-visible syntax error -- just signals a syntax that WREC doesn't support yet.
-const char* Parser::CharacterClassUnmatched = "missing terminating ] for character class";
-const char* Parser::CharacterClassOutOfOrder = "range out of order in character class";
-const char* Parser::EscapeUnterminated = "\\ at end of pattern";
-
-class PatternCharacterSequence {
-typedef Generator::JumpList JumpList;
-
-public:
-    PatternCharacterSequence(Generator& generator, JumpList& failures)
-        : m_generator(generator)
-        , m_failures(failures)
-    {
-    }
-    
-    size_t size() { return m_sequence.size(); }
-    
-    void append(int ch)
-    {
-        m_sequence.append(ch);
-    }
-    
-    void flush()
-    {
-        if (!m_sequence.size())
-            return;
-
-        m_generator.generatePatternCharacterSequence(m_failures, m_sequence.begin(), m_sequence.size());
-        m_sequence.clear();
-    }
-
-    void flush(const Quantifier& quantifier)
-    {
-        if (!m_sequence.size())
-            return;
-
-        m_generator.generatePatternCharacterSequence(m_failures, m_sequence.begin(), m_sequence.size() - 1);
-
-        switch (quantifier.type) {
-        case Quantifier::None:
-        case Quantifier::Error:
-            ASSERT_NOT_REACHED();
-            break;
-
-        case Quantifier::Greedy: {
-            GeneratePatternCharacterFunctor functor(m_sequence.last());
-            m_generator.generateGreedyQuantifier(m_failures, functor, quantifier.min, quantifier.max);
-            break;
-        }
-        
-        case Quantifier::NonGreedy: {
-            GeneratePatternCharacterFunctor functor(m_sequence.last());
-            m_generator.generateNonGreedyQuantifier(m_failures, functor, quantifier.min, quantifier.max);
-            break;
-        }
-        }
-        
-        m_sequence.clear();
-    }
-
-private:
-    Generator& m_generator;
-    JumpList& m_failures;
-    Vector<int, 8> m_sequence;
-};
-
-ALWAYS_INLINE Quantifier Parser::consumeGreedyQuantifier()
-{
-    switch (peek()) {
-        case '?':
-            consume();
-            return Quantifier(Quantifier::Greedy, 0, 1);
-
-        case '*':
-            consume();
-            return Quantifier(Quantifier::Greedy, 0);
-
-        case '+':
-            consume();
-            return Quantifier(Quantifier::Greedy, 1);
-
-        case '{': {
-            SavedState state(*this);
-            consume();
-
-            // Accept: {n}, {n,}, {n,m}.
-            // Reject: {n,m} where n > m.
-            // Ignore: Anything else, such as {n, m}.
-
-            if (!peekIsDigit()) {
-                state.restore();
-                return Quantifier();
-            }
-
-            unsigned min = consumeNumber();
-            unsigned max = min;
-
-            if (peek() == ',') {
-                consume();
-                max = peekIsDigit() ? consumeNumber() : Quantifier::Infinity;
-            }
-
-            if (peek() != '}') {
-                state.restore();
-                return Quantifier();
-            }
-            consume();
-            if (min > max) {
-                setError(QuantifierOutOfOrder);
-                return Quantifier(Quantifier::Error);
-            }
-
-            return Quantifier(Quantifier::Greedy, min, max);
-         }
-
-         default:
-            return Quantifier(); // No quantifier.
-    }
-}
-
-Quantifier Parser::consumeQuantifier()
-{
-    Quantifier q = consumeGreedyQuantifier();
-    
-    if ((q.type == Quantifier::Greedy) && (peek() == '?')) {
-        consume();
-        q.type = Quantifier::NonGreedy;
-    }
-    
-    return q;
-}
-
-bool Parser::parseCharacterClassQuantifier(JumpList& failures, const CharacterClass& charClass, bool invert)
-{
-    Quantifier q = consumeQuantifier();
-
-    switch (q.type) {
-    case Quantifier::None: {
-        m_generator.generateCharacterClass(failures, charClass, invert);
-        break;
-    }
-
-    case Quantifier::Greedy: {
-        GenerateCharacterClassFunctor functor(&charClass, invert);
-        m_generator.generateGreedyQuantifier(failures, functor, q.min, q.max);
-        break;
-    }
-
-    case Quantifier::NonGreedy: {
-        GenerateCharacterClassFunctor functor(&charClass, invert);
-        m_generator.generateNonGreedyQuantifier(failures, functor, q.min, q.max);
-        break;
-    }
-
-    case Quantifier::Error:
-        return false;
-    }
-    
-    return true;
-}
-
-bool Parser::parseBackreferenceQuantifier(JumpList& failures, unsigned subpatternId)
-{
-    Quantifier q = consumeQuantifier();
-
-    switch (q.type) {
-    case Quantifier::None: {
-        m_generator.generateBackreference(failures, subpatternId);
-        break;
-    }
-
-    case Quantifier::Greedy:
-    case Quantifier::NonGreedy:
-        m_generator.generateBackreferenceQuantifier(failures, q.type, subpatternId, q.min, q.max);
-        return true;
-
-    case Quantifier::Error:
-        return false;
-    }
-    
-    return true;
-}
-
-bool Parser::parseParentheses(JumpList& failures)
-{
-    ParenthesesType type = consumeParenthesesType();
-
-    // FIXME: WREC originally failed to backtrack correctly in cases such as
-    // "c".match(/(.*)c/). Now, most parentheses handling is disabled. For
-    // unsupported parentheses, we fall back on PCRE.
-
-    switch (type) {
-        case Generator::Assertion: {
-            m_generator.generateParenthesesAssertion(failures);
-
-            if (consume() != ')') {
-                setError(ParenthesesUnmatched);
-                return false;
-            }
-
-            Quantifier quantifier = consumeQuantifier();
-            if (quantifier.type != Quantifier::None && quantifier.min == 0) {
-                setError(ParenthesesNotSupported);
-                return false;
-            }
-
-            return true;
-        }
-        case Generator::InvertedAssertion: {
-            m_generator.generateParenthesesInvertedAssertion(failures);
-
-            if (consume() != ')') {
-                setError(ParenthesesUnmatched);
-                return false;
-            }
-
-            Quantifier quantifier = consumeQuantifier();
-            if (quantifier.type != Quantifier::None && quantifier.min == 0) {
-                setError(ParenthesesNotSupported);
-                return false;
-            }
-
-            return true;
-        }
-        default:
-            setError(ParenthesesNotSupported);
-            return false;
-    }
-}
-
-bool Parser::parseCharacterClass(JumpList& failures)
-{
-    bool invert = false;
-    if (peek() == '^') {
-        consume();
-        invert = true;
-    }
-
-    CharacterClassConstructor constructor(m_ignoreCase);
-
-    int ch;
-    while ((ch = peek()) != ']') {
-        switch (ch) {
-        case EndOfPattern:
-            setError(CharacterClassUnmatched);
-            return false;
-
-        case '\\': {
-            consume();
-            Escape escape = consumeEscape(true);
-
-            switch (escape.type()) {
-                case Escape::PatternCharacter: {
-                    int character = PatternCharacterEscape::cast(escape).character();
-                    if (character == '-')
-                        constructor.flushBeforeEscapedHyphen();
-                    constructor.put(character);
-                    break;
-                }
-                case Escape::CharacterClass: {
-                    const CharacterClassEscape& characterClassEscape = CharacterClassEscape::cast(escape);
-                    ASSERT(!characterClassEscape.invert());
-                    constructor.append(characterClassEscape.characterClass());
-                    break;
-                }
-                case Escape::Error:
-                    return false;
-                case Escape::Backreference:
-                case Escape::WordBoundaryAssertion: {
-                    ASSERT_NOT_REACHED();
-                    break;
-                }
-            }
-            break;
-        }
-
-        default:
-            consume();
-            constructor.put(ch);
-        }
-    }
-    consume();
-
-    // lazily catch reversed ranges ([z-a])in character classes
-    if (constructor.isUpsideDown()) {
-        setError(CharacterClassOutOfOrder);
-        return false;
-    }
-
-    constructor.flush();
-    CharacterClass charClass = constructor.charClass();
-    return parseCharacterClassQuantifier(failures, charClass, invert);
-}
-
-bool Parser::parseNonCharacterEscape(JumpList& failures, const Escape& escape)
-{
-    switch (escape.type()) {
-        case Escape::PatternCharacter:
-            ASSERT_NOT_REACHED();
-            return false;
-
-        case Escape::CharacterClass:
-            return parseCharacterClassQuantifier(failures, CharacterClassEscape::cast(escape).characterClass(), CharacterClassEscape::cast(escape).invert());
-
-        case Escape::Backreference:
-            return parseBackreferenceQuantifier(failures, BackreferenceEscape::cast(escape).subpatternId());
-
-        case Escape::WordBoundaryAssertion:
-            m_generator.generateAssertionWordBoundary(failures, WordBoundaryAssertionEscape::cast(escape).invert());
-            return true;
-
-        case Escape::Error:
-            return false;
-    }
-
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
-Escape Parser::consumeEscape(bool inCharacterClass)
-{
-    switch (peek()) {
-    case EndOfPattern:
-        setError(EscapeUnterminated);
-        return Escape(Escape::Error);
-
-    // Assertions
-    case 'b':
-        consume();
-        if (inCharacterClass)
-            return PatternCharacterEscape('\b');
-        return WordBoundaryAssertionEscape(false); // do not invert
-    case 'B':
-        consume();
-        if (inCharacterClass)
-            return PatternCharacterEscape('B');
-        return WordBoundaryAssertionEscape(true); // invert
-
-    // CharacterClassEscape
-    case 'd':
-        consume();
-        return CharacterClassEscape(CharacterClass::digits(), false);
-    case 's':
-        consume();
-        return CharacterClassEscape(CharacterClass::spaces(), false);
-    case 'w':
-        consume();
-        return CharacterClassEscape(CharacterClass::wordchar(), false);
-    case 'D':
-        consume();
-        return inCharacterClass
-            ? CharacterClassEscape(CharacterClass::nondigits(), false)
-            : CharacterClassEscape(CharacterClass::digits(), true);
-    case 'S':
-        consume();
-        return inCharacterClass
-            ? CharacterClassEscape(CharacterClass::nonspaces(), false)
-            : CharacterClassEscape(CharacterClass::spaces(), true);
-    case 'W':
-        consume();
-        return inCharacterClass
-            ? CharacterClassEscape(CharacterClass::nonwordchar(), false)
-            : CharacterClassEscape(CharacterClass::wordchar(), true);
-
-    // DecimalEscape
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9': {
-        if (peekDigit() > m_numSubpatterns || inCharacterClass) {
-            // To match Firefox, we parse an invalid backreference in the range [1-7]
-            // as an octal escape.
-            return peekDigit() > 7 ? PatternCharacterEscape('\\') : PatternCharacterEscape(consumeOctal());
-        }
-
-        int value = 0;
-        do {
-            unsigned newValue = value * 10 + peekDigit();
-            if (newValue > m_numSubpatterns)
-                break;
-            value = newValue;
-            consume();
-        } while (peekIsDigit());
-
-        return BackreferenceEscape(value);
-    }
-
-    // Octal escape
-    case '0':
-        consume();
-        return PatternCharacterEscape(consumeOctal());
-
-    // ControlEscape
-    case 'f':
-        consume();
-        return PatternCharacterEscape('\f');
-    case 'n':
-        consume();
-        return PatternCharacterEscape('\n');
-    case 'r':
-        consume();
-        return PatternCharacterEscape('\r');
-    case 't':
-        consume();
-        return PatternCharacterEscape('\t');
-    case 'v':
-        consume();
-        return PatternCharacterEscape('\v');
-
-    // ControlLetter
-    case 'c': {
-        SavedState state(*this);
-        consume();
-        
-        int control = consume();
-        // To match Firefox, inside a character class, we also accept numbers
-        // and '_' as control characters.
-        if ((!inCharacterClass && !isASCIIAlpha(control)) || (!isASCIIAlphanumeric(control) && control != '_')) {
-            state.restore();
-            return PatternCharacterEscape('\\');
-        }
-        return PatternCharacterEscape(control & 31);
-    }
-
-    // HexEscape
-    case 'x': {
-        consume();
-
-        SavedState state(*this);
-        int x = consumeHex(2);
-        if (x == -1) {
-            state.restore();
-            return PatternCharacterEscape('x');
-        }
-        return PatternCharacterEscape(x);
-    }
-
-    // UnicodeEscape
-    case 'u': {
-        consume();
-
-        SavedState state(*this);
-        int x = consumeHex(4);
-        if (x == -1) {
-            state.restore();
-            return PatternCharacterEscape('u');
-        }
-        return PatternCharacterEscape(x);
-    }
-
-    // IdentityEscape
-    default:
-        return PatternCharacterEscape(consume());
-    }
-}
-
-void Parser::parseAlternative(JumpList& failures)
-{
-    PatternCharacterSequence sequence(m_generator, failures);
-
-    while (1) {
-        switch (peek()) {
-        case EndOfPattern:
-        case '|':
-        case ')':
-            sequence.flush();
-            return;
-
-        case '*':
-        case '+':
-        case '?':
-        case '{': {
-            Quantifier q = consumeQuantifier();
-
-            if (q.type == Quantifier::None) {
-                sequence.append(consume());
-                continue;
-            }
-
-            if (q.type == Quantifier::Error)
-                return;
-
-            if (!sequence.size()) {
-                setError(QuantifierWithoutAtom);
-                return;
-            }
-
-            sequence.flush(q);
-            continue;
-        }
-
-        case '^':
-            consume();
-
-            sequence.flush();
-            m_generator.generateAssertionBOL(failures);
-            continue;
-
-        case '$':
-            consume();
-
-            sequence.flush();
-            m_generator.generateAssertionEOL(failures);
-            continue;
-
-        case '.':
-            consume();
-
-            sequence.flush();
-            if (!parseCharacterClassQuantifier(failures, CharacterClass::newline(), true))
-                return;
-            continue;
-
-        case '[':
-            consume();
-
-            sequence.flush();
-            if (!parseCharacterClass(failures))
-                return;
-            continue;
-
-        case '(':
-            consume();
-
-            sequence.flush();
-            if (!parseParentheses(failures))
-                return;
-            continue;
-
-        case '\\': {
-            consume();
-
-            Escape escape = consumeEscape(false);
-            if (escape.type() == Escape::PatternCharacter) {
-                sequence.append(PatternCharacterEscape::cast(escape).character());
-                continue;
-            }
-
-            sequence.flush();
-            if (!parseNonCharacterEscape(failures, escape))
-                return;
-            continue;
-        }
-
-        default:
-            sequence.append(consume());
-            continue;
-        }
-    }
-}
-
-/*
-  TOS holds index.
-*/
-void Parser::parseDisjunction(JumpList& failures)
-{
-    parseAlternative(failures);
-    if (peek() != '|')
-        return;
-
-    JumpList successes;
-    do {
-        consume();
-        m_generator.terminateAlternative(successes, failures);
-        parseAlternative(failures);
-    } while (peek() == '|');
-
-    m_generator.terminateDisjunction(successes);
-}
-
-Generator::ParenthesesType Parser::consumeParenthesesType()
-{
-    if (peek() != '?')
-        return Generator::Capturing;
-    consume();
-
-    switch (consume()) {
-    case ':':
-        return Generator::NonCapturing;
-    
-    case '=':
-        return Generator::Assertion;
-
-    case '!':
-        return Generator::InvertedAssertion;
-
-    default:
-        setError(ParenthesesTypeInvalid);
-        return Generator::Error;
-    }
-}
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
diff --git a/wrec/WRECParser.h b/wrec/WRECParser.h
deleted file mode 100644 (file)
index a3e151b..0000000
+++ /dev/null
@@ -1,214 +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 Parser_h
-#define Parser_h
-
-#include <wtf/Platform.h>
-
-#if ENABLE(WREC)
-
-#include "Escapes.h"
-#include "Quantifier.h"
-#include "UString.h"
-#include "WRECGenerator.h"
-#include <wtf/ASCIICType.h>
-
-namespace JSC { namespace WREC {
-
-    struct CharacterClass;
-
-    class Parser {
-    typedef Generator::JumpList JumpList;
-    typedef Generator::ParenthesesType ParenthesesType;
-
-    friend class SavedState;
-
-    public:
-        Parser(const UString& pattern, bool ignoreCase, bool multiline)
-            : m_generator(*this)
-            , m_data(pattern.data())
-            , m_size(pattern.size())
-            , m_ignoreCase(ignoreCase)
-            , m_multiline(multiline)
-        {
-            reset();
-        }
-        
-        Generator& generator() { return m_generator; }
-
-        bool ignoreCase() const { return m_ignoreCase; }
-        bool multiline() const { return m_multiline; }
-
-        void recordSubpattern() { ++m_numSubpatterns; }
-        unsigned numSubpatterns() const { return m_numSubpatterns; }
-        
-        const char* error() const { return m_error; }
-        const char* syntaxError() const { return m_error == ParenthesesNotSupported ? 0 : m_error; }
-        
-        void parsePattern(JumpList& failures)
-        {
-            reset();
-
-            parseDisjunction(failures);
-
-            if (peek() != EndOfPattern)
-                setError(ParenthesesUnmatched); // Parsing the pattern should fully consume it.
-        }
-
-        void parseDisjunction(JumpList& failures);
-        void parseAlternative(JumpList& failures);
-        bool parseTerm(JumpList& failures);
-        bool parseNonCharacterEscape(JumpList& failures, const Escape&);
-        bool parseParentheses(JumpList& failures);
-        bool parseCharacterClass(JumpList& failures);
-        bool parseCharacterClassQuantifier(JumpList& failures, const CharacterClass& charClass, bool invert);
-        bool parseBackreferenceQuantifier(JumpList& failures, unsigned subpatternId);
-
-    private:
-        class SavedState {
-        public:
-            SavedState(Parser& parser)
-                : m_parser(parser)
-                , m_index(parser.m_index)
-            {
-            }
-            
-            void restore()
-            {
-                m_parser.m_index = m_index;
-            }
-
-        private:
-            Parser& m_parser;
-            unsigned m_index;
-        };
-
-        void reset()
-        {
-            m_index = 0;
-            m_numSubpatterns = 0;
-            m_error = 0;
-        }
-
-        void setError(const char* error)
-        {
-            if (m_error)
-                return;
-            m_error = error;
-        }
-
-        int peek()
-        {
-            if (m_index >= m_size)
-                return EndOfPattern;
-            return m_data[m_index];
-        }
-
-        int consume()
-        {
-            if (m_index >= m_size)
-                return EndOfPattern;
-            return m_data[m_index++];
-        }
-
-        bool peekIsDigit()
-        {
-            return WTF::isASCIIDigit(peek());
-        }
-
-        unsigned peekDigit()
-        {
-            ASSERT(peekIsDigit());
-            return peek() - '0';
-        }
-
-        unsigned consumeDigit()
-        {
-            ASSERT(peekIsDigit());
-            return consume() - '0';
-        }
-
-        unsigned consumeNumber()
-        {
-            int n = consumeDigit();
-            while (peekIsDigit()) {
-                n *= 10;
-                n += consumeDigit();
-            }
-            return n;
-        }
-
-        int consumeHex(int count)
-        {
-            int n = 0;
-            while (count--) {
-                if (!WTF::isASCIIHexDigit(peek()))
-                    return -1;
-                n = (n << 4) | WTF::toASCIIHexValue(consume());
-            }
-            return n;
-        }
-
-        unsigned consumeOctal()
-        {
-            unsigned n = 0;
-            while (n < 32 && WTF::isASCIIOctalDigit(peek()))
-                n = n * 8 + consumeDigit();
-            return n;
-        }
-        
-        ALWAYS_INLINE Quantifier consumeGreedyQuantifier();
-        Quantifier consumeQuantifier();
-        Escape consumeEscape(bool inCharacterClass);
-        ParenthesesType consumeParenthesesType();
-
-        static const int EndOfPattern = -1;
-
-        // Error messages.
-        static const char* QuantifierOutOfOrder;
-        static const char* QuantifierWithoutAtom;
-        static const char* ParenthesesUnmatched;
-        static const char* ParenthesesTypeInvalid;
-        static const char* ParenthesesNotSupported;
-        static const char* CharacterClassUnmatched;
-        static const char* CharacterClassOutOfOrder;
-        static const char* EscapeUnterminated;
-
-        Generator m_generator;
-        const UChar* m_data;
-        unsigned m_size;
-        unsigned m_index;
-        bool m_ignoreCase;
-        bool m_multiline;
-        unsigned m_numSubpatterns;
-        const char* m_error;
-    };
-
-} } // namespace JSC::WREC
-
-#endif // ENABLE(WREC)
-
-#endif // Parser_h
diff --git a/wscript b/wscript
index f5a041f77d4b7eccadd4b47fcc9f97c738a98bd9..61ad1fbc972b7dc2a165a12827e3d7137785b159 100644 (file)
--- a/wscript
+++ b/wscript
@@ -30,7 +30,7 @@ import commands
 from settings import *
 
 jscore_excludes = ['jsc.cpp', 'ucptable.cpp']
 from settings import *
 
 jscore_excludes = ['jsc.cpp', 'ucptable.cpp']
-jscore_excludes.extend(get_excludes(jscore_dir, ['*CF.cpp', '*Symbian.cpp']))
+jscore_excludes.extend(get_excludes(jscore_dir, ['*Brew.cpp', '*CF.cpp', '*Symbian.cpp']))
 
 sources = []
 
 
 sources = []
 
@@ -72,11 +72,13 @@ def build(bld):
     full_dirs = get_dirs_for_features(jscore_dir, features=[build_port], dirs=jscore_dirs)
 
     includes = common_includes + full_dirs
     full_dirs = get_dirs_for_features(jscore_dir, features=[build_port], dirs=jscore_dirs)
 
     includes = common_includes + full_dirs
+    if sys.platform.startswith('darwin'):
+        includes.append(os.path.join(jscore_dir, 'icu'))
 
     # 1. A simple program
     jscore = bld.new_task_gen(
         features = 'cxx cstaticlib',
 
     # 1. A simple program
     jscore = bld.new_task_gen(
         features = 'cxx cstaticlib',
-        includes = '. .. assembler wrec DerivedSources ForwardingHeaders ' + ' '.join(includes),
+        includes = '. .. assembler DerivedSources ForwardingHeaders ' + ' '.join(includes),
         source = sources,
         target = 'jscore',
         uselib = 'WX ICU ' + get_config(),
         source = sources,
         target = 'jscore',
         uselib = 'WX ICU ' + get_config(),
@@ -87,7 +89,7 @@ def build(bld):
         
     obj = bld.new_task_gen(
         features = 'cxx cprogram',
         
     obj = bld.new_task_gen(
         features = 'cxx cprogram',
-        includes = '. .. assembler wrec DerivedSources ForwardingHeaders ' + ' '.join(includes),
+        includes = '. .. assembler DerivedSources ForwardingHeaders ' + ' '.join(includes),
         source = 'jsc.cpp',
         target = 'jsc',
         uselib = 'WX ICU ' + get_config(),
         source = 'jsc.cpp',
         target = 'jsc',
         uselib = 'WX ICU ' + get_config(),
index 0c3c29fb3acf22d188f899f019f70768d8a65366..b43bb378514c9fbb52908ba9c0b1a0edd6067aa1 100644 (file)
@@ -30,7 +30,6 @@
 #define WTF_ASCIICType_h
 
 #include <wtf/Assertions.h>
 #define WTF_ASCIICType_h
 
 #include <wtf/Assertions.h>
-#include <wtf/Platform.h>
 
 // The behavior of many of the functions in the <ctype.h> header is dependent
 // on the current locale. But in the WebKit project, all uses of those functions
 
 // The behavior of many of the functions in the <ctype.h> header is dependent
 // on the current locale. But in the WebKit project, all uses of those functions
index 4e7224caf0e77c1ba8effb6965fae3dfcd8dab09..34f8b74b837b9c35ec08201d4d2ab632ac935b09 100644 (file)
@@ -33,6 +33,8 @@
 #ifndef NEVER_INLINE
 #if COMPILER(GCC)
 #define NEVER_INLINE __attribute__((__noinline__))
 #ifndef NEVER_INLINE
 #if COMPILER(GCC)
 #define NEVER_INLINE __attribute__((__noinline__))
+#elif COMPILER(RVCT)
+#define NEVER_INLINE __declspec(noinline)
 #else
 #define NEVER_INLINE
 #endif
 #else
 #define NEVER_INLINE
 #endif
 #ifndef NO_RETURN
 #if COMPILER(GCC)
 #define NO_RETURN __attribute((__noreturn__))
 #ifndef NO_RETURN
 #if COMPILER(GCC)
 #define NO_RETURN __attribute((__noreturn__))
+#elif COMPILER(MSVC) || COMPILER(RVCT)
+#define NO_RETURN __declspec(noreturn)
 #else
 #define NO_RETURN
 #endif
 #endif
 #else
 #define NO_RETURN
 #endif
 #endif
+
+#ifndef NO_RETURN_WITH_VALUE
+#if !COMPILER(MSVC)
+#define NO_RETURN_WITH_VALUE NO_RETURN
+#else
+#define NO_RETURN_WITH_VALUE
+#endif
+#endif
index 365903046f965a6bcb0f4e09dc5c13e812b9fc69..168e8ba0e7c3e7efcea0bae150874cb6bf4ebdb2 100644 (file)
 #endif
 
 #ifdef NDEBUG
 #endif
 
 #ifdef NDEBUG
+/* Disable ASSERT* macros in release mode. */
 #define ASSERTIONS_DISABLED_DEFAULT 1
 #else
 #define ASSERTIONS_DISABLED_DEFAULT 0
 #endif
 
 #define ASSERTIONS_DISABLED_DEFAULT 1
 #else
 #define ASSERTIONS_DISABLED_DEFAULT 0
 #endif
 
-#if COMPILER(MSVC7) || COMPILER(WINSCW)
+#if COMPILER(MSVC7_OR_LOWER) || COMPILER(WINSCW)
 #define HAVE_VARIADIC_MACRO 0
 #else
 #define HAVE_VARIADIC_MACRO 1
 #define HAVE_VARIADIC_MACRO 0
 #else
 #define HAVE_VARIADIC_MACRO 1
@@ -157,8 +158,14 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
 }
 #endif
 
 }
 #endif
 
-/* CRASH -- gets us into the debugger or the crash reporter -- signals are ignored by the crash reporter so we must do better */
+/* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
 
 
+   Use CRASH() in response to known, unrecoverable errors like out-of-memory.
+   Macro is enabled in both debug and release mode.
+   To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
+
+   Signals are ignored by the crash reporter on OS X so we must do better.
+*/
 #ifndef CRASH
 #if OS(SYMBIAN)
 #define CRASH() do { \
 #ifndef CRASH
 #if OS(SYMBIAN)
 #define CRASH() do { \
@@ -173,7 +180,11 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
 #endif
 #endif
 
 #endif
 #endif
 
-/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED */
+/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
+
+  These macros are compiled out of release builds.
+  Expressions inside them are evaluated in debug builds only.
+*/
 
 #if OS(WINCE) && !PLATFORM(TORCHMOBILE)
 /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
 
 #if OS(WINCE) && !PLATFORM(TORCHMOBILE)
 /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
@@ -188,6 +199,14 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
 #undef ASSERT
 #endif
 
 #undef ASSERT
 #endif
 
+#if PLATFORM(BREWMP)
+/* FIXME: We include this here only to avoid a conflict with the COMPILE_ASSERT macro. */
+#include <AEEClassIDs.h>
+
+/* FIXME: Change to use something other than COMPILE_ASSERT to avoid this conflict with the underlying platform */
+#undef COMPILE_ASSERT
+#endif
+
 #if ASSERT_DISABLED
 
 #define ASSERT(assertion) ((void)0)
 #if ASSERT_DISABLED
 
 #define ASSERT(assertion) ((void)0)
@@ -214,7 +233,7 @@ while (0)
 
 /* ASSERT_WITH_MESSAGE */
 
 
 /* ASSERT_WITH_MESSAGE */
 
-#if COMPILER(MSVC7)
+#if COMPILER(MSVC7_OR_LOWER)
 #define ASSERT_WITH_MESSAGE(assertion) ((void)0)
 #elif COMPILER(WINSCW)
 #define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0)
 #define ASSERT_WITH_MESSAGE(assertion) ((void)0)
 #elif COMPILER(WINSCW)
 #define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0)
@@ -254,7 +273,7 @@ while (0)
 
 /* FATAL */
 
 
 /* FATAL */
 
-#if COMPILER(MSVC7)
+#if COMPILER(MSVC7_OR_LOWER)
 #define FATAL() ((void)0)
 #elif COMPILER(WINSCW)
 #define FATAL(arg...) ((void)0)
 #define FATAL() ((void)0)
 #elif COMPILER(WINSCW)
 #define FATAL(arg...) ((void)0)
@@ -269,7 +288,7 @@ while (0)
 
 /* LOG_ERROR */
 
 
 /* LOG_ERROR */
 
-#if COMPILER(MSVC7)
+#if COMPILER(MSVC7_OR_LOWER)
 #define LOG_ERROR() ((void)0)
 #elif COMPILER(WINSCW)
 #define LOG_ERROR(arg...)  ((void)0)
 #define LOG_ERROR() ((void)0)
 #elif COMPILER(WINSCW)
 #define LOG_ERROR(arg...)  ((void)0)
@@ -281,7 +300,7 @@ while (0)
 
 /* LOG */
 
 
 /* LOG */
 
-#if COMPILER(MSVC7)
+#if COMPILER(MSVC7_OR_LOWER)
 #define LOG() ((void)0)
 #elif COMPILER(WINSCW)
 #define LOG(arg...) ((void)0)
 #define LOG() ((void)0)
 #elif COMPILER(WINSCW)
 #define LOG(arg...) ((void)0)
@@ -295,7 +314,7 @@ while (0)
 
 /* LOG_VERBOSE */
 
 
 /* LOG_VERBOSE */
 
-#if COMPILER(MSVC7)
+#if COMPILER(MSVC7_OR_LOWER)
 #define LOG_VERBOSE(channel) ((void)0)
 #elif COMPILER(WINSCW)
 #define LOG_VERBOSE(channel, arg...) ((void)0)
 #define LOG_VERBOSE(channel) ((void)0)
 #elif COMPILER(WINSCW)
 #define LOG_VERBOSE(channel, arg...) ((void)0)
diff --git a/wtf/Atomics.h b/wtf/Atomics.h
new file mode 100644 (file)
index 0000000..1d190a3
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007, 2008, 2010 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.
+ *
+ *
+ * Note: The implementations of InterlockedIncrement and InterlockedDecrement are based
+ * on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license
+ * is virtually identical to the Apple license above but is included here for completeness.
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ * 
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ * 
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef Atomics_h
+#define Atomics_h
+
+#include "Platform.h"
+
+#if OS(WINDOWS)
+#include <windows.h>
+#elif OS(DARWIN)
+#include <libkern/OSAtomic.h>
+#elif OS(ANDROID)
+#include <cutils/atomic.h>
+#elif COMPILER(GCC) && !OS(SYMBIAN)
+#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
+#include <ext/atomicity.h>
+#else
+#include <bits/atomicity.h>
+#endif
+#endif
+
+namespace WTF {
+
+#if OS(WINDOWS)
+#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
+
+#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE)
+inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }
+inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
+#else
+inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); }
+inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }
+#endif
+
+#elif OS(DARWIN)
+#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
+
+inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }
+inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }
+
+#elif OS(ANDROID)
+
+inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); }
+inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); }
+
+#elif COMPILER(GCC) && !CPU(SPARC64) && !OS(SYMBIAN) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc
+#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
+
+inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; }
+inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; }
+
+#endif
+
+} // namespace WTF
+
+#if USE(LOCKFREE_THREADSAFESHARED)
+using WTF::atomicDecrement;
+using WTF::atomicIncrement;
+#endif
+
+#endif // Atomics_h
diff --git a/wtf/Complex.h b/wtf/Complex.h
new file mode 100644 (file)
index 0000000..cfd1d20
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2010 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:
+ *
+ * 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 Complex_h
+#define Complex_h
+
+#include <complex>
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+typedef std::complex<double> Complex;
+
+inline Complex complexFromMagnitudePhase(double magnitude, double phase)
+{
+    return Complex(magnitude * cos(phase), magnitude * sin(phase));
+}
+
+} // namespace WebCore
+
+#endif // Complex_h
index b2728747bbb51559f10b74a128e44065459d23c0..08fffa288b0b8c65c5bb2375c5b5e5cf6ed9c579 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
  * Copyright (C) 2008 Google Inc. All rights reserved.
  * Copyright (C) 2007-2009 Torch Mobile, Inc.
  *
  * Copyright (C) 2008 Google Inc. All rights reserved.
  * Copyright (C) 2007-2009 Torch Mobile, Inc.
  *
@@ -53,13 +53,13 @@ extern "C" time_t mktime(struct tm *t);
 #endif
 #endif
 
 #endif
 #endif
 
-#elif PLATFORM(CF)
-#include <CoreFoundation/CFDate.h>
 #elif PLATFORM(GTK)
 #include <glib.h>
 #elif PLATFORM(WX)
 #include <wx/datetime.h>
 #elif PLATFORM(GTK)
 #include <glib.h>
 #elif PLATFORM(WX)
 #include <wx/datetime.h>
-#else // Posix systems relying on the gettimeofday()
+#elif PLATFORM(BREWMP)
+#include <AEEStdLib.h>
+#else
 #include <sys/time.h>
 #endif
 
 #include <sys/time.h>
 #endif
 
@@ -249,13 +249,6 @@ double currentTime()
 
 #endif // USE(QUERY_PERFORMANCE_COUNTER)
 
 
 #endif // USE(QUERY_PERFORMANCE_COUNTER)
 
-#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
 #elif PLATFORM(GTK)
 
 // Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides
@@ -277,15 +270,27 @@ double currentTime()
     return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0);
 }
 
     return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0);
 }
 
-#else // Other Posix systems rely on the gettimeofday().
+#elif PLATFORM(BREWMP)
 
 
+// GETUTCSECONDS returns the number of seconds since 1980/01/06 00:00:00 UTC,
+// and GETTIMEMS returns the number of milliseconds that have elapsed since the last
+// occurrence of 00:00:00 local time.
+// We can combine GETUTCSECONDS and GETTIMEMS to calculate the number of milliseconds
+// since 1970/01/01 00:00:00 UTC.
 double currentTime()
 {
 double currentTime()
 {
-    struct timeval now;
-    struct timezone zone;
+    // diffSeconds is the number of seconds from 1970/01/01 to 1980/01/06
+    const unsigned diffSeconds = 315964800;
+    return static_cast<double>(diffSeconds + GETUTCSECONDS() + ((GETTIMEMS() % 1000) / msPerSecond));
+}
+
+#else
 
 
-    gettimeofday(&now, &zone);
-    return static_cast<double>(now.tv_sec) + (double)(now.tv_usec / 1000000.0);
+double currentTime()
+{
+    struct timeval now;
+    gettimeofday(&now, 0);
+    return now.tv_sec + now.tv_usec / 1000000.0;
 }
 
 #endif
 }
 
 #endif
index 334a6e98a5c46685e394ade369cc1f9d547ed5f5..dcb1f6c69d9b3f15ece01f15c5d1bf9c625c7fc0 100644 (file)
@@ -49,7 +49,7 @@ namespace WTF {
 
     inline void getLocalTime(const time_t* localTime, struct tm* localTM)
     {
 
     inline void getLocalTime(const time_t* localTime, struct tm* localTM)
     {
-    #if COMPILER(MSVC7) || COMPILER(MINGW) || OS(WINCE)
+    #if COMPILER(MSVC7_OR_LOWER) || COMPILER(MINGW) || OS(WINCE)
         *localTM = *localtime(localTime);
     #elif COMPILER(MSVC)
         localtime_s(localTM, localTime);
         *localTM = *localtime(localTime);
     #elif COMPILER(MSVC)
         localtime_s(localTM, localTime);
@@ -61,6 +61,7 @@ namespace WTF {
 } // namespace WTF
 
 using WTF::currentTime;
 } // namespace WTF
 
 using WTF::currentTime;
+using WTF::getLocalTime;
 
 #endif // CurrentTime_h
 
 
 #endif // CurrentTime_h
 
index 520f08e4a7de61184218805ec99cbfc1285e6674..e3b25bda9e361900ec156a5c7bb2509dc3a3d7b9 100644 (file)
@@ -82,6 +82,9 @@
 #if ENABLE(JSC_MULTIPLE_THREADS)
 #include <pthread.h>
 #endif
 #if ENABLE(JSC_MULTIPLE_THREADS)
 #include <pthread.h>
 #endif
+#if USE(PTHREAD_GETSPECIFIC_DIRECT)
+#include <System/pthread_machdep.h>
+#endif
 
 #ifndef NO_TCMALLOC_SAMPLES
 #ifdef WTF_CHANGES
 
 #ifndef NO_TCMALLOC_SAMPLES
 #ifdef WTF_CHANGES
@@ -200,6 +203,16 @@ TryMallocReturnValue tryFastZeroedMalloc(size_t n)
 
 #if FORCE_SYSTEM_MALLOC
 
 
 #if FORCE_SYSTEM_MALLOC
 
+#if PLATFORM(BREWMP)
+#include "brew/SystemMallocBrew.h"
+#endif
+
+#if OS(DARWIN)
+#include <malloc/malloc.h>
+#elif COMPILER(MSVC)
+#include <malloc.h>
+#endif
+
 namespace WTF {
 
 TryMallocReturnValue tryFastMalloc(size_t n) 
 namespace WTF {
 
 TryMallocReturnValue tryFastMalloc(size_t n) 
@@ -235,8 +248,16 @@ void* fastMalloc(size_t n)
     void* result = malloc(n);
 #endif
 
     void* result = malloc(n);
 #endif
 
-    if (!result)
+    if (!result) {
+#if PLATFORM(BREWMP)
+        // The behavior of malloc(0) is implementation defined.
+        // To make sure that fastMalloc never returns 0, retry with fastMalloc(1).
+        if (!n)
+            return fastMalloc(1);
+#endif
         CRASH();
         CRASH();
+    }
+
     return result;
 }
 
     return result;
 }
 
@@ -275,8 +296,16 @@ void* fastCalloc(size_t n_elements, size_t element_size)
     void* result = calloc(n_elements, element_size);
 #endif
 
     void* result = calloc(n_elements, element_size);
 #endif
 
-    if (!result)
+    if (!result) {
+#if PLATFORM(BREWMP)
+        // If either n_elements or element_size is 0, the behavior of calloc is implementation defined.
+        // To make sure that fastCalloc never returns 0, retry with fastCalloc(1, 1).
+        if (!n_elements || !element_size)
+            return fastCalloc(1, 1);
+#endif
         CRASH();
         CRASH();
+    }
+
     return result;
 }
 
     return result;
 }
 
@@ -345,10 +374,21 @@ void releaseFastMallocFreeMemory() { }
     
 FastMallocStatistics fastMallocStatistics()
 {
     
 FastMallocStatistics fastMallocStatistics()
 {
-    FastMallocStatistics statistics = { 0, 0, 0, 0 };
+    FastMallocStatistics statistics = { 0, 0, 0 };
     return statistics;
 }
 
     return statistics;
 }
 
+size_t fastMallocSize(const void* p)
+{
+#if OS(DARWIN)
+    return malloc_size(p);
+#elif COMPILER(MSVC)
+    return _msize(const_cast<void*>(p));
+#else
+    return 1;
+#endif
+}
+
 } // namespace WTF
 
 #if OS(DARWIN)
 } // namespace WTF
 
 #if OS(DARWIN)
@@ -376,7 +416,6 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
 #include <algorithm>
 #include <errno.h>
 #include <limits>
 #include <algorithm>
 #include <errno.h>
 #include <limits>
-#include <new>
 #include <pthread.h>
 #include <stdarg.h>
 #include <stddef.h>
 #include <pthread.h>
 #include <stdarg.h>
 #include <stddef.h>
@@ -391,7 +430,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
 #include <windows.h>
 #endif
 
 #include <windows.h>
 #endif
 
-#if WTF_CHANGES
+#ifdef WTF_CHANGES
 
 #if OS(DARWIN)
 #include "MallocZoneSupport.h"
 
 #if OS(DARWIN)
 #include "MallocZoneSupport.h"
@@ -411,10 +450,15 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
 // call to the function on Mac OS X, and it's used in performance-critical code. So we
 // use a function pointer. But that's not necessarily faster on other platforms, and we had
 // problems with this technique on Windows, so we'll do this only on Mac OS X.
 // call to the function on Mac OS X, and it's used in performance-critical code. So we
 // use a function pointer. But that's not necessarily faster on other platforms, and we had
 // problems with this technique on Windows, so we'll do this only on Mac OS X.
+#if USE(PTHREAD_GETSPECIFIC_DIRECT)
+#define pthread_getspecific(key) _pthread_getspecific_direct(key)
+#define pthread_setspecific(key, val) _pthread_setspecific_direct(key, (val))
+#else
 #if OS(DARWIN)
 static void* (*pthread_getspecific_function_pointer)(pthread_key_t) = pthread_getspecific;
 #define pthread_getspecific(key) pthread_getspecific_function_pointer(key)
 #endif
 #if OS(DARWIN)
 static void* (*pthread_getspecific_function_pointer)(pthread_key_t) = pthread_getspecific;
 #define pthread_getspecific(key) pthread_getspecific_function_pointer(key)
 #endif
+#endif
 
 #define DEFINE_VARIABLE(type, name, value, meaning) \
   namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \
 
 #define DEFINE_VARIABLE(type, name, value, meaning) \
   namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead {  \
@@ -440,7 +484,7 @@ namespace WTF {
 #define CHECK_CONDITION ASSERT
 
 #if OS(DARWIN)
 #define CHECK_CONDITION ASSERT
 
 #if OS(DARWIN)
-class Span;
+struct Span;
 class TCMalloc_Central_FreeListPadded;
 class TCMalloc_PageHeap;
 class TCMalloc_ThreadCache;
 class TCMalloc_Central_FreeListPadded;
 class TCMalloc_PageHeap;
 class TCMalloc_ThreadCache;
@@ -1212,29 +1256,34 @@ template <> class MapSelector<32> {
 // -------------------------------------------------------------------------
 
 #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
 // -------------------------------------------------------------------------
 
 #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 OS(WINDOWS)
-// 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
+// The page heap maintains a free list for spans that are no longer in use by
+// the central cache or any thread caches. We use a background thread to
+// periodically scan the free list and release a percentage of it back to the OS.
+
+// If free_committed_pages_ exceeds kMinimumFreeCommittedPageCount, the
+// background thread:
+//     - wakes up
+//     - pauses for kScavengeDelayInSeconds
+//     - returns to the OS a percentage of the memory that remained unused during
+//       that pause (kScavengePercentage * min_free_committed_pages_since_last_scavenge_)
+// The goal of this strategy is to reduce memory pressure in a timely fashion
+// while avoiding thrashing the OS allocator.
+
+// Time delay before the page heap scavenger will consider returning pages to
+// the OS.
+static const int kScavengeDelayInSeconds = 2;
+
+// Approximate percentage of free committed pages to return to the OS in one
+// scavenge.
+static const float kScavengePercentage = .5f;
+
+// number of span lists to keep spans in when memory is returned.
+static const int kMinSpanListsWithSpans = 32;
+
+// Number of free committed pages that we want to keep around.  The minimum number of pages used when there
+// is 1 span in each of the first kMinSpanListsWithSpans spanlists.  Currently 528 pages.
+static const size_t kMinimumFreeCommittedPageCount = kMinSpanListsWithSpans * ((1.0f+kMinSpanListsWithSpans) / 2.0f);
+
 #endif
 
 class TCMalloc_PageHeap {
 #endif
 
 class TCMalloc_PageHeap {
@@ -1340,8 +1389,9 @@ class TCMalloc_PageHeap {
   // Number of pages kept in free lists that are still committed.
   Length free_committed_pages_;
 
   // 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_;
+  // Minimum number of free committed pages since last scavenge. (Can be 0 if
+  // we've committed new pages since the last scavenge.)
+  Length min_free_committed_pages_since_last_scavenge_;
 #endif
 
   bool GrowHeap(Length n);
 #endif
 
   bool GrowHeap(Length n);
@@ -1386,13 +1436,13 @@ class TCMalloc_PageHeap {
   void initializeScavenger();
   ALWAYS_INLINE void signalScavenger();
   void scavenge();
   void initializeScavenger();
   ALWAYS_INLINE void signalScavenger();
   void scavenge();
-  ALWAYS_INLINE bool shouldContinueScavenging() const;
+  ALWAYS_INLINE bool shouldScavenge() const;
 
 #if !HAVE(DISPATCH_H)
 
 #if !HAVE(DISPATCH_H)
-  static NO_RETURN void* runScavengerThread(void*);
+  static NO_RETURN_WITH_VALUE void* runScavengerThread(void*);
   NO_RETURN void scavengerThread();
 
   NO_RETURN void scavengerThread();
 
-  // Keeps track of whether the background thread is actively scavenging memory every kScavengeTimerDelayInSeconds, or
+  // Keeps track of whether the background thread is actively scavenging memory every kScavengeDelayInSeconds, or
   // it's blocked waiting for more pages to be deleted.
   bool m_scavengeThreadActive;
 
   // it's blocked waiting for more pages to be deleted.
   bool m_scavengeThreadActive;
 
@@ -1418,7 +1468,7 @@ void TCMalloc_PageHeap::init()
 
 #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
   free_committed_pages_ = 0;
 
 #if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
   free_committed_pages_ = 0;
-  pages_committed_since_last_scavenge_ = 0;
+  min_free_committed_pages_since_last_scavenge_ = 0;
 #endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
 
   scavenge_counter_ = 0;
 #endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
 
   scavenge_counter_ = 0;
@@ -1461,7 +1511,7 @@ void* TCMalloc_PageHeap::runScavengerThread(void* context)
 
 ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
 {
 
 ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
 {
-  if (!m_scavengeThreadActive && shouldContinueScavenging())
+  if (!m_scavengeThreadActive && shouldScavenge())
     pthread_cond_signal(&m_scavengeCondition);
 }
 
     pthread_cond_signal(&m_scavengeCondition);
 }
 
@@ -1471,15 +1521,15 @@ void TCMalloc_PageHeap::initializeScavenger()
 {
   m_scavengeQueue = dispatch_queue_create("com.apple.JavaScriptCore.FastMallocSavenger", NULL);
   m_scavengeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_scavengeQueue);
 {
   m_scavengeQueue = dispatch_queue_create("com.apple.JavaScriptCore.FastMallocSavenger", NULL);
   m_scavengeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_scavengeQueue);
-  dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, kScavengeTimerDelayInSeconds * NSEC_PER_SEC);
-  dispatch_source_set_timer(m_scavengeTimer, startTime, kScavengeTimerDelayInSeconds * NSEC_PER_SEC, 1000 * NSEC_PER_USEC);
+  dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, kScavengeDelayInSeconds * NSEC_PER_SEC);
+  dispatch_source_set_timer(m_scavengeTimer, startTime, kScavengeDelayInSeconds * NSEC_PER_SEC, 1000 * NSEC_PER_USEC);
   dispatch_source_set_event_handler(m_scavengeTimer, ^{ periodicScavenge(); });
   m_scavengingScheduled = false;
 }
 
 ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
 {
   dispatch_source_set_event_handler(m_scavengeTimer, ^{ periodicScavenge(); });
   m_scavengingScheduled = false;
 }
 
 ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
 {
-  if (!m_scavengingScheduled && shouldContinueScavenging()) {
+  if (!m_scavengingScheduled && shouldScavenge()) {
     m_scavengingScheduled = true;
     dispatch_resume(m_scavengeTimer);
   }
     m_scavengingScheduled = true;
     dispatch_resume(m_scavengeTimer);
   }
@@ -1487,42 +1537,37 @@ ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
 
 #endif
 
 
 #endif
 
-void TCMalloc_PageHeap::scavenge() 
+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;
+    size_t pagesToRelease = min_free_committed_pages_since_last_scavenge_ * kScavengePercentage;
+    size_t targetPageCount = std::max<size_t>(kMinimumFreeCommittedPageCount, free_committed_pages_ - pagesToRelease);
+
+    while (free_committed_pages_ > targetPageCount) {
+        for (int i = kMaxPages; i > 0 && free_committed_pages_ >= targetPageCount; i--) {
+            SpanList* slist = (static_cast<size_t>(i) == kMaxPages) ? &large_ : &free_[i];
+            // If the span size is bigger than kMinSpanListsWithSpans pages return all the spans in the list, else return all but 1 span.  
+            // Return only 50% of a spanlist at a time so spans of size 1 are not the only ones left.
+            size_t numSpansToReturn = (i > kMinSpanListsWithSpans) ? DLL_Length(&slist->normal) : static_cast<size_t>(.5 * DLL_Length(&slist->normal));
+            for (int j = 0; static_cast<size_t>(j) < numSpansToReturn && !DLL_IsEmpty(&slist->normal) && free_committed_pages_ > targetPageCount; j++) {
+                Span* s = slist->normal.prev; 
+                DLL_Remove(s);
+                ASSERT(!s->decommitted);
+                if (!s->decommitted) {
+                    TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift),
+                                           static_cast<size_t>(s->length << kPageShift));
+                    ASSERT(free_committed_pages_ >= s->length);
+                    free_committed_pages_ -= s->length;
+                    s->decommitted = true;
+                }
+                DLL_Prepend(&slist->returned, s);
             }
             }
-            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;
+
+    min_free_committed_pages_since_last_scavenge_ = free_committed_pages_;
 }
 
 }
 
-ALWAYS_INLINE bool TCMalloc_PageHeap::shouldContinueScavenging() const 
+ALWAYS_INLINE bool TCMalloc_PageHeap::shouldScavenge() const 
 {
     return free_committed_pages_ > kMinimumFreeCommittedPageCount; 
 }
 {
     return free_committed_pages_ > kMinimumFreeCommittedPageCount; 
 }
@@ -1551,20 +1596,13 @@ inline Span* TCMalloc_PageHeap::New(Length n) {
 
     Span* result = ll->next;
     Carve(result, n, released);
 
     Span* result = ll->next;
     Carve(result, n, released);
-    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
 #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;
-    }
+    // 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;
+    if (free_committed_pages_ < min_free_committed_pages_since_last_scavenge_) 
+      min_free_committed_pages_since_last_scavenge_ = free_committed_pages_;
 #endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
     ASSERT(Check());
     free_pages_ -= n;
 #endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
     ASSERT(Check());
     free_pages_ -= n;
@@ -1622,20 +1660,13 @@ Span* TCMalloc_PageHeap::AllocLarge(Length n) {
 
   if (best != NULL) {
     Carve(best, n, from_released);
 
   if (best != NULL) {
     Carve(best, n, from_released);
-    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
 #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;
-    }
+    // 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;
+    if (free_committed_pages_ < min_free_committed_pages_since_last_scavenge_)
+      min_free_committed_pages_since_last_scavenge_ = free_committed_pages_;
 #endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
     ASSERT(Check());
     free_pages_ -= n;
 #endif  // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
     ASSERT(Check());
     free_pages_ -= n;
@@ -1661,29 +1692,34 @@ Span* TCMalloc_PageHeap::Split(Span* span, Length n) {
   return leftover;
 }
 
   return leftover;
 }
 
-static ALWAYS_INLINE void propagateDecommittedState(Span* destination, Span* source)
-{
-    destination->decommitted = source->decommitted;
-}
-
 inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) {
   ASSERT(n > 0);
   DLL_Remove(span);
   span->free = 0;
   Event(span, 'A', n);
 
 inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) {
   ASSERT(n > 0);
   DLL_Remove(span);
   span->free = 0;
   Event(span, 'A', n);
 
+  if (released) {
+    // If the span chosen to carve from is decommited, commit the entire span at once to avoid committing spans 1 page at a time.
+    ASSERT(span->decommitted);
+    TCMalloc_SystemCommit(reinterpret_cast<void*>(span->start << kPageShift), static_cast<size_t>(span->length << kPageShift));
+    span->decommitted = false;
+#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
+    free_committed_pages_ += span->length;
+#endif
+  }
+  
   const int extra = static_cast<int>(span->length - n);
   ASSERT(extra >= 0);
   if (extra > 0) {
     Span* leftover = NewSpan(span->start + n, extra);
     leftover->free = 1;
   const int extra = static_cast<int>(span->length - n);
   ASSERT(extra >= 0);
   if (extra > 0) {
     Span* leftover = NewSpan(span->start + n, extra);
     leftover->free = 1;
-    propagateDecommittedState(leftover, span);
+    leftover->decommitted = false;
     Event(leftover, 'S', extra);
     RecordSpan(leftover);
 
     // Place leftover span on appropriate free list
     SpanList* listpair = (static_cast<size_t>(extra) < kMaxPages) ? &free_[extra] : &large_;
     Event(leftover, 'S', extra);
     RecordSpan(leftover);
 
     // Place leftover span on appropriate free list
     SpanList* listpair = (static_cast<size_t>(extra) < kMaxPages) ? &free_[extra] : &large_;
-    Span* dst = released ? &listpair->returned : &listpair->normal;
+    Span* dst = &listpair->normal;
     DLL_Prepend(dst, leftover);
 
     span->length = n;
     DLL_Prepend(dst, leftover);
 
     span->length = n;
@@ -1778,6 +1814,8 @@ inline void TCMalloc_PageHeap::Delete(Span* span) {
       // 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;
       // 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;
+      if (free_committed_pages_ < min_free_committed_pages_since_last_scavenge_)
+            min_free_committed_pages_since_last_scavenge_ = free_committed_pages_;
   } else {
       // If the merged span remains committed, add the deleted span's size to the free committed pages count.
       free_committed_pages_ += n;
   } else {
       // If the merged span remains committed, add the deleted span's size to the free committed pages count.
       free_committed_pages_ += n;
@@ -1940,10 +1978,6 @@ bool TCMalloc_PageHeap::GrowHeap(Length n) {
   }
   ask = actual_size >> kPageShift;
 
   }
   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;
   uint64_t old_system_bytes = system_bytes_;
   system_bytes_ += (ask << kPageShift);
   const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
@@ -2133,10 +2167,10 @@ class TCMalloc_ThreadCache {
   // Total byte size in cache
   size_t Size() const { return size_; }
 
   // Total byte size in cache
   size_t Size() const { return size_; }
 
-  void* Allocate(size_t size);
+  ALWAYS_INLINE void* Allocate(size_t size);
   void Deallocate(void* ptr, size_t size_class);
 
   void Deallocate(void* ptr, size_t size_class);
 
-  void FetchFromCentralCache(size_t cl, size_t allocationSize);
+  ALWAYS_INLINE void FetchFromCentralCache(size_t cl, size_t allocationSize);
   void ReleaseToCentralCache(size_t cl, int N);
   void Scavenge();
   void Print() const;
   void ReleaseToCentralCache(size_t cl, int N);
   void Scavenge();
   void Print() const;
@@ -2237,12 +2271,12 @@ class TCMalloc_Central_FreeList {
   // REQUIRES: lock_ is held
   // Release an object to spans.
   // May temporarily release lock_.
   // REQUIRES: lock_ is held
   // Release an object to spans.
   // May temporarily release lock_.
-  void ReleaseToSpans(void* object);
+  ALWAYS_INLINE void ReleaseToSpans(void* object);
 
   // REQUIRES: lock_ is held
   // Populate cache by fetching from the page heap.
   // May temporarily release lock_.
 
   // REQUIRES: lock_ is held
   // Populate cache by fetching from the page heap.
   // May temporarily release lock_.
-  void Populate();
+  ALWAYS_INLINE void Populate();
 
   // REQUIRES: lock is held.
   // Tries to make room for a TCEntry.  If the cache is full it will try to
 
   // REQUIRES: lock is held.
   // Tries to make room for a TCEntry.  If the cache is full it will try to
@@ -2255,7 +2289,7 @@ class TCMalloc_Central_FreeList {
   // just iterates over the sizeclasses but does so without taking a lock.
   // Returns true on success.
   // May temporarily lock a "random" size class.
   // just iterates over the sizeclasses but does so without taking a lock.
   // Returns true on success.
   // May temporarily lock a "random" size class.
-  static bool EvictRandomSizeClass(size_t locked_size_class, bool force);
+  static ALWAYS_INLINE bool EvictRandomSizeClass(size_t locked_size_class, bool force);
 
   // REQUIRES: lock_ is *not* held.
   // Tries to shrink the Cache.  If force is true it will relase objects to
 
   // REQUIRES: lock_ is *not* held.
   // Tries to shrink the Cache.  If force is true it will relase objects to
@@ -2310,7 +2344,7 @@ static SpinLock pageheap_lock = SPINLOCK_INITIALIZER;
 #if PLATFORM(ARM)
 static void* pageheap_memory[(sizeof(TCMalloc_PageHeap) + sizeof(void*) - 1) / sizeof(void*)] __attribute__((aligned));
 #else
 #if PLATFORM(ARM)
 static void* pageheap_memory[(sizeof(TCMalloc_PageHeap) + sizeof(void*) - 1) / sizeof(void*)] __attribute__((aligned));
 #else
-static void* pageheap_memory[(sizeof(TCMalloc_PageHeap) + sizeof(void*) - 1) / sizeof(void*)];
+static AllocAlignmentInteger pageheap_memory[(sizeof(TCMalloc_PageHeap) + sizeof(AllocAlignmentInteger) - 1) / sizeof(AllocAlignmentInteger)];
 #endif
 static bool phinited = false;
 
 #endif
 static bool phinited = false;
 
@@ -2346,15 +2380,15 @@ void TCMalloc_PageHeap::scavengerThread()
 #endif
 
   while (1) {
 #endif
 
   while (1) {
-      if (!shouldContinueScavenging()) {
+      if (!shouldScavenge()) {
           pthread_mutex_lock(&m_scavengeMutex);
           m_scavengeThreadActive = false;
           pthread_mutex_lock(&m_scavengeMutex);
           m_scavengeThreadActive = false;
-          // Block until there are enough freed pages to release back to the system.
+          // Block until there are enough free committed pages to release back to the system.
           pthread_cond_wait(&m_scavengeCondition, &m_scavengeMutex);
           m_scavengeThreadActive = true;
           pthread_mutex_unlock(&m_scavengeMutex);
       }
           pthread_cond_wait(&m_scavengeCondition, &m_scavengeMutex);
           m_scavengeThreadActive = true;
           pthread_mutex_unlock(&m_scavengeMutex);
       }
-      sleep(kScavengeTimerDelayInSeconds);
+      sleep(kScavengeDelayInSeconds);
       {
           SpinLockHolder h(&pageheap_lock);
           pageheap->scavenge();
       {
           SpinLockHolder h(&pageheap_lock);
           pageheap->scavenge();
@@ -2371,7 +2405,7 @@ void TCMalloc_PageHeap::periodicScavenge()
     pageheap->scavenge();
   }
 
     pageheap->scavenge();
   }
 
-  if (!shouldContinueScavenging()) {
+  if (!shouldScavenge()) {
     m_scavengingScheduled = false;
     dispatch_suspend(m_scavengeTimer);
   }
     m_scavengingScheduled = false;
     dispatch_suspend(m_scavengeTimer);
   }
@@ -2396,7 +2430,11 @@ static __thread TCMalloc_ThreadCache *threadlocal_heap;
 // Therefore, we use TSD keys only after tsd_inited is set to true.
 // Until then, we use a slow path to get the heap object.
 static bool tsd_inited = false;
 // Therefore, we use TSD keys only after tsd_inited is set to true.
 // Until then, we use a slow path to get the heap object.
 static bool tsd_inited = false;
+#if USE(PTHREAD_GETSPECIFIC_DIRECT)
+static pthread_key_t heap_key = __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0;
+#else
 static pthread_key_t heap_key;
 static pthread_key_t heap_key;
+#endif
 #if COMPILER(MSVC)
 DWORD tlsIndex = TLS_OUT_OF_INDEXES;
 #endif
 #if COMPILER(MSVC)
 DWORD tlsIndex = TLS_OUT_OF_INDEXES;
 #endif
@@ -2940,7 +2978,11 @@ inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCacheIfPresent() {
 
 void TCMalloc_ThreadCache::InitTSD() {
   ASSERT(!tsd_inited);
 
 void TCMalloc_ThreadCache::InitTSD() {
   ASSERT(!tsd_inited);
+#if USE(PTHREAD_GETSPECIFIC_DIRECT)
+  pthread_key_init_np(heap_key, DestroyThreadCache);
+#else
   pthread_key_create(&heap_key, DestroyThreadCache);
   pthread_key_create(&heap_key, DestroyThreadCache);
+#endif
 #if COMPILER(MSVC)
   tlsIndex = TlsAlloc();
 #endif
 #if COMPILER(MSVC)
   tlsIndex = TlsAlloc();
 #endif
@@ -3654,7 +3696,7 @@ extern "C"
 #define do_malloc do_malloc<crashOnFailure>
 
 template <bool crashOnFailure>
 #define do_malloc do_malloc<crashOnFailure>
 
 template <bool crashOnFailure>
-void* malloc(size_t);
+ALWAYS_INLINE void* malloc(size_t);
 
 void* fastMalloc(size_t size)
 {
 
 void* fastMalloc(size_t size)
 {
@@ -3715,7 +3757,7 @@ void free(void* ptr) {
 extern "C" 
 #else
 template <bool crashOnFailure>
 extern "C" 
 #else
 template <bool crashOnFailure>
-void* calloc(size_t, size_t);
+ALWAYS_INLINE void* calloc(size_t, size_t);
 
 void* fastCalloc(size_t n, size_t elem_size)
 {
 
 void* fastCalloc(size_t n, size_t elem_size)
 {
@@ -3779,7 +3821,7 @@ void cfree(void* ptr) {
 extern "C" 
 #else
 template <bool crashOnFailure>
 extern "C" 
 #else
 template <bool crashOnFailure>
-void* realloc(void*, size_t);
+ALWAYS_INLINE void* realloc(void*, size_t);
 
 void* fastRealloc(void* old_ptr, size_t new_size)
 {
 
 void* fastRealloc(void* old_ptr, size_t new_size)
 {
@@ -3916,6 +3958,8 @@ static inline void* cpp_alloc(size_t size, bool nothrow) {
   }
 }
 
   }
 }
 
+#if ENABLE(GLOBAL_FASTMALLOC_NEW)
+
 void* operator new(size_t size) {
   void* p = cpp_alloc(size, false);
   // We keep this next instruction out of cpp_alloc for a reason: when
 void* operator new(size_t size) {
   void* p = cpp_alloc(size, false);
   // We keep this next instruction out of cpp_alloc for a reason: when
@@ -3970,6 +4014,8 @@ void operator delete[](void* p, const std::nothrow_t&) __THROW {
   do_free(p);
 }
 
   do_free(p);
 }
 
+#endif
+
 extern "C" void* memalign(size_t align, size_t size) __THROW {
   void* result = do_memalign(align, size);
   MallocHook::InvokeNewHook(result, size);
 extern "C" void* memalign(size_t align, size_t size) __THROW {
   void* result = do_memalign(align, size);
   MallocHook::InvokeNewHook(result, size);
@@ -4085,7 +4131,62 @@ void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride;
 
 #endif
 
 
 #endif
 
-#if defined(WTF_CHANGES) && OS(DARWIN)
+#ifdef WTF_CHANGES
+void releaseFastMallocFreeMemory()
+{
+    // Flush free pages in the current thread cache back to the page heap.
+    // Low watermark mechanism in Scavenge() prevents full return on the first pass.
+    // The second pass flushes everything.
+    if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent()) {
+        threadCache->Scavenge();
+        threadCache->Scavenge();
+    }
+
+    SpinLockHolder h(&pageheap_lock);
+    pageheap->ReleaseFreePages();
+}
+    
+FastMallocStatistics fastMallocStatistics()
+{
+    FastMallocStatistics statistics;
+
+    SpinLockHolder lockHolder(&pageheap_lock);
+    statistics.reservedVMBytes = static_cast<size_t>(pageheap->SystemBytes());
+    statistics.committedVMBytes = statistics.reservedVMBytes - pageheap->ReturnedBytes();
+
+    statistics.freeListBytes = 0;
+    for (unsigned cl = 0; cl < kNumClasses; ++cl) {
+        const int length = central_cache[cl].length();
+        const int tc_length = central_cache[cl].tc_length();
+
+        statistics.freeListBytes += ByteSizeForClass(cl) * (length + tc_length);
+    }
+    for (TCMalloc_ThreadCache* threadCache = thread_heaps; threadCache ; threadCache = threadCache->next_)
+        statistics.freeListBytes += threadCache->Size();
+
+    return statistics;
+}
+
+size_t fastMallocSize(const void* ptr)
+{
+    const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
+    Span* span = pageheap->GetDescriptorEnsureSafe(p);
+
+    if (!span || span->free)
+        return 0;
+
+    for (void* free = span->objects; free != NULL; free = *((void**) free)) {
+        if (ptr == free)
+            return 0;
+    }
+
+    if (size_t cl = span->sizeclass)
+        return ByteSizeForClass(cl);
+
+    return span->length << kPageShift;
+}
+
+#if OS(DARWIN)
 
 class FreeObjectFinder {
     const RemoteMemoryReader& m_reader;
 
 class FreeObjectFinder {
     const RemoteMemoryReader& m_reader;
@@ -4368,12 +4469,7 @@ extern "C" {
 malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print,
     &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics
 
 malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print,
     &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics
 
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) || PLATFORM(IPHONE)
     , 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher.
     , 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher.
-#endif
-#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !OS(IPHONE_OS)
-    , 0, 0, 0, 0 // These members will not be used unless the zone advertises itself as version seven or higher.
-#endif
 
     };
 }
 
     };
 }
@@ -4405,44 +4501,9 @@ void FastMallocZone::init()
     static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Central_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator);
 }
 
     static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Central_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator);
 }
 
-#endif
-
-#if WTF_CHANGES
-void releaseFastMallocFreeMemory()
-{
-    // Flush free pages in the current thread cache back to the page heap.
-    // Low watermark mechanism in Scavenge() prevents full return on the first pass.
-    // The second pass flushes everything.
-    if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent()) {
-        threadCache->Scavenge();
-        threadCache->Scavenge();
-    }
-
-    SpinLockHolder h(&pageheap_lock);
-    pageheap->ReleaseFreePages();
-}
-    
-FastMallocStatistics fastMallocStatistics()
-{
-    FastMallocStatistics statistics;
-    {
-        SpinLockHolder lockHolder(&pageheap_lock);
-        statistics.heapSize = static_cast<size_t>(pageheap->SystemBytes());
-        statistics.freeSizeInHeap = static_cast<size_t>(pageheap->FreeBytes());
-        statistics.returnedSize = pageheap->ReturnedBytes();
-        statistics.freeSizeInCaches = 0;
-        for (TCMalloc_ThreadCache* threadCache = thread_heaps; threadCache ; threadCache = threadCache->next_)
-            statistics.freeSizeInCaches += threadCache->Size();
-    }
-    for (unsigned cl = 0; cl < kNumClasses; ++cl) {
-        const int length = central_cache[cl].length();
-        const int tc_length = central_cache[cl].tc_length();
-        statistics.freeSizeInCaches += ByteSizeForClass(cl) * (length + tc_length);
-    }
-    return statistics;
-}
+#endif // OS(DARWIN)
 
 } // namespace WTF
 
 } // namespace WTF
-#endif
+#endif // WTF_CHANGES
 
 #endif // FORCE_SYSTEM_MALLOC
 
 #endif // FORCE_SYSTEM_MALLOC
index 74d43070aa3326455466b151373c540ba8b11236..1ccd6a64e05d05babac01ab094314e1f553cc74a 100644 (file)
@@ -34,6 +34,7 @@ namespace WTF {
     void* fastCalloc(size_t numElements, size_t elementSize);
     void* fastRealloc(void*, size_t);
     char* fastStrDup(const char*);
     void* fastCalloc(size_t numElements, size_t elementSize);
     void* fastRealloc(void*, size_t);
     char* fastStrDup(const char*);
+    size_t fastMallocSize(const void*);
 
     struct TryMallocReturnValue {
         TryMallocReturnValue(void* data)
 
     struct TryMallocReturnValue {
         TryMallocReturnValue(void* data)
@@ -82,10 +83,9 @@ namespace WTF {
     void releaseFastMallocFreeMemory();
     
     struct FastMallocStatistics {
     void releaseFastMallocFreeMemory();
     
     struct FastMallocStatistics {
-        size_t heapSize;
-        size_t freeSizeInHeap;
-        size_t freeSizeInCaches;
-        size_t returnedSize;
+        size_t reservedVMBytes;
+        size_t committedVMBytes;
+        size_t freeListBytes;
     };
     FastMallocStatistics fastMallocStatistics();
 
     };
     FastMallocStatistics fastMallocStatistics();
 
@@ -180,16 +180,17 @@ namespace WTF {
 
 } // namespace WTF
 
 
 } // namespace WTF
 
-using WTF::fastMalloc;
-using WTF::fastZeroedMalloc;
 using WTF::fastCalloc;
 using WTF::fastCalloc;
+using WTF::fastFree;
+using WTF::fastMalloc;
+using WTF::fastMallocSize;
 using WTF::fastRealloc;
 using WTF::fastRealloc;
-using WTF::tryFastMalloc;
-using WTF::tryFastZeroedMalloc;
+using WTF::fastStrDup;
+using WTF::fastZeroedMalloc;
 using WTF::tryFastCalloc;
 using WTF::tryFastCalloc;
+using WTF::tryFastMalloc;
 using WTF::tryFastRealloc;
 using WTF::tryFastRealloc;
-using WTF::fastFree;
-using WTF::fastStrDup;
+using WTF::tryFastZeroedMalloc;
 
 #ifndef NDEBUG    
 using WTF::fastMallocForbid;
 
 #ifndef NDEBUG    
 using WTF::fastMallocForbid;
@@ -215,8 +216,7 @@ using WTF::fastMallocAllow;
 // debug-only code to make sure we don't use the system malloc via the default operator
 // new by accident.
 
 // debug-only code to make sure we don't use the system malloc via the default operator
 // new by accident.
 
-// We musn't customize the global operator new and delete for the Qt port.
-#if !PLATFORM(QT)
+#if ENABLE(GLOBAL_FASTMALLOC_NEW)
 
 #if COMPILER(MSVC)
 #pragma warning(push)
 
 #if COMPILER(MSVC)
 #pragma warning(push)
index 165eb41346b8b15de4e0e4c97826afcc1b6cc7c9..4ed75c517906fcc2efc97ed2fdd16fb227a999cb 100644 (file)
@@ -43,7 +43,7 @@ namespace WTF {
         int capacity() const;
         bool isEmpty() const;
         
         int capacity() const;
         bool isEmpty() const;
         
-        // iterators iterate over pairs of values and counts
+        // Iterators iterate over pairs of values and counts.
         iterator begin();
         iterator end();
         const_iterator begin() const;
         iterator begin();
         iterator end();
         const_iterator begin() const;
@@ -54,21 +54,21 @@ namespace WTF {
         bool contains(const ValueType&) const;
         unsigned count(const ValueType&) const;
 
         bool contains(const ValueType&) const;
         unsigned count(const ValueType&) const;
 
-        // increases the count if an equal value is already present
-        // the return value is a pair of an interator to the new value's location, 
-        // and a bool that is true if an new entry was added
+        // Increases the count if an equal value is already present
+        // the return value is a pair of an interator to the new value's 
+        // location, and a bool that is true if an new entry was added.
         std::pair<iterator, bool> add(const ValueType&);
         
         std::pair<iterator, bool> add(const ValueType&);
         
-        // reduces the count of the value, and removes it if count
-        // goes down to zero
-        void remove(const ValueType&);
-        void remove(iterator);
+        // Reduces the count of the value, and removes it if count
+        // goes down to zero, returns true if the value is removed.
+        bool remove(const ValueType&);
+        bool remove(iterator);
  
  
-        // removes the value, regardless of its count
+        // Removes the value, regardless of its count.
         void removeAll(iterator);
         void removeAll(const ValueType&);
 
         void removeAll(iterator);
         void removeAll(const ValueType&);
 
-        // clears the whole set
+        // Clears the whole set.
         void clear();
 
     private:
         void clear();
 
     private:
@@ -150,24 +150,27 @@ namespace WTF {
     }
     
     template<typename Value, typename HashFunctions, typename Traits>
     }
     
     template<typename Value, typename HashFunctions, typename Traits>
-    inline void HashCountedSet<Value, HashFunctions, Traits>::remove(const ValueType& value)
+    inline bool HashCountedSet<Value, HashFunctions, Traits>::remove(const ValueType& value)
     {
     {
-        remove(find(value));
+        return remove(find(value));
     }
     
     template<typename Value, typename HashFunctions, typename Traits>
     }
     
     template<typename Value, typename HashFunctions, typename Traits>
-    inline void HashCountedSet<Value, HashFunctions, Traits>::remove(iterator it)
+    inline bool HashCountedSet<Value, HashFunctions, Traits>::remove(iterator it)
     {
         if (it == end())
     {
         if (it == end())
-            return;
+            return false;
 
         unsigned oldVal = it->second;
 
         unsigned oldVal = it->second;
-        ASSERT(oldVal != 0);
+        ASSERT(oldVal);
         unsigned newVal = oldVal - 1;
         unsigned newVal = oldVal - 1;
-        if (newVal == 0)
-            m_impl.remove(it);
-        else
+        if (newVal) {
             it->second = newVal;
             it->second = newVal;
+            return false;
+        }
+
+        m_impl.remove(it);
+        return true;
     }
     
     template<typename Value, typename HashFunctions, typename Traits>
     }
     
     template<typename Value, typename HashFunctions, typename Traits>
index d63a8d4560f212bc00915d99a54a6049c21cca39..09094d1ad50de8f679a05515671035eeb434bc27 100644 (file)
@@ -133,9 +133,10 @@ namespace WTF {
 
         static unsigned hash(const T& key) { return Translator::hash(key); }
         static bool equal(const KeyType& a, const T& b) { return Translator::equal(a, b); }
 
         static unsigned hash(const T& key) { return Translator::hash(key); }
         static bool equal(const KeyType& a, const T& b) { return Translator::equal(a, b); }
-        static void translate(ValueType& location, const T& key, const MappedType&, unsigned hashCode)
+        static void translate(ValueType& location, const T& key, const MappedType& mapped, unsigned hashCode)
         {
             Translator::translate(location.first, key, hashCode);
         {
             Translator::translate(location.first, key, hashCode);
+            location.second = mapped;
         }
     };
 
         }
     };
 
index 54ed36b2a9639fcd53999edcb051af9c95030a27..09355ade40a3ade2c5a70431f9b6205da8c42011 100644 (file)
@@ -37,27 +37,27 @@ namespace WTF {
     // and an append that moves the element to the end even if already present,
     // but unclear yet if these are needed.
 
     // and an append that moves the element to the end even if already present,
     // but unclear yet if these are needed.
 
-    template<typename Value, typename HashFunctions> class ListHashSet;
+    template<typename Value, size_t inlineCapacity, typename HashFunctions> class ListHashSet;
 
     template<typename T> struct IdentityExtractor;
 
 
     template<typename T> struct IdentityExtractor;
 
-    template<typename Value, typename HashFunctions>
-    void deleteAllValues(const ListHashSet<Value, HashFunctions>&);
+    template<typename Value, size_t inlineCapacity, typename HashFunctions>
+    void deleteAllValues(const ListHashSet<Value, inlineCapacity, HashFunctions>&);
 
 
-    template<typename ValueArg, typename HashArg> class ListHashSetIterator;
-    template<typename ValueArg, typename HashArg> class ListHashSetConstIterator;
+    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator;
+    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator;
 
 
-    template<typename ValueArg> struct ListHashSetNode;
-    template<typename ValueArg> struct ListHashSetNodeAllocator;
-    template<typename ValueArg, typename HashArg> struct ListHashSetNodeHashFunctions;
+    template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode;
+    template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator;
+    template<typename ValueArg, size_t inlineCapacity, typename HashArg> struct ListHashSetNodeHashFunctions;
 
 
-    template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet : public FastAllocBase {
+    template<typename ValueArg, size_t inlineCapacity = 256, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet : public FastAllocBase {
     private:
     private:
-        typedef ListHashSetNode<ValueArg> Node;
-        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;
+        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
+        typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator;
 
         typedef HashTraits<Node*> NodeTraits;
 
         typedef HashTraits<Node*> NodeTraits;
-        typedef ListHashSetNodeHashFunctions<ValueArg, HashArg> NodeHash;
+        typedef ListHashSetNodeHashFunctions<ValueArg, inlineCapacity, HashArg> NodeHash;
 
         typedef HashTable<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplType;
         typedef HashTableIterator<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplTypeIterator;
 
         typedef HashTable<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplType;
         typedef HashTableIterator<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplTypeIterator;
@@ -67,10 +67,10 @@ namespace WTF {
 
     public:
         typedef ValueArg ValueType;
 
     public:
         typedef ValueArg ValueType;
-        typedef ListHashSetIterator<ValueType, HashArg> iterator;
-        typedef ListHashSetConstIterator<ValueType, HashArg> const_iterator;
+        typedef ListHashSetIterator<ValueType, inlineCapacity, HashArg> iterator;
+        typedef ListHashSetConstIterator<ValueType, inlineCapacity, HashArg> const_iterator;
 
 
-        friend class ListHashSetConstIterator<ValueType, HashArg>;
+        friend class ListHashSetConstIterator<ValueType, inlineCapacity, HashArg>;
 
         ListHashSet();
         ListHashSet(const ListHashSet&);
 
         ListHashSet();
         ListHashSet(const ListHashSet&);
@@ -119,9 +119,9 @@ namespace WTF {
         OwnPtr<NodeAllocator> m_allocator;
     };
 
         OwnPtr<NodeAllocator> m_allocator;
     };
 
-    template<typename ValueArg> struct ListHashSetNodeAllocator {
-        typedef ListHashSetNode<ValueArg> Node;
-        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;
+    template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator {
+        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
+        typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator;
 
         ListHashSetNodeAllocator() 
             : m_freeList(pool())
 
         ListHashSetNodeAllocator() 
             : m_freeList(pool())
@@ -181,15 +181,15 @@ namespace WTF {
 
         Node* m_freeList;
         bool m_isDoneWithInitialFreeList;
 
         Node* m_freeList;
         bool m_isDoneWithInitialFreeList;
-        static const size_t m_poolSize = 256;
+        static const size_t m_poolSize = inlineCapacity;
         union {
             char pool[sizeof(Node) * m_poolSize];
             double forAlignment;
         } m_pool;
     };
 
         union {
             char pool[sizeof(Node) * m_poolSize];
             double forAlignment;
         } m_pool;
     };
 
-    template<typename ValueArg> struct ListHashSetNode {
-        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;
+    template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode {
+        typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator;
 
         ListHashSetNode(ValueArg value)
             : m_value(value)
 
         ListHashSetNode(ValueArg value)
             : m_value(value)
@@ -220,25 +220,25 @@ namespace WTF {
 #endif
     };
 
 #endif
     };
 
-    template<typename ValueArg, typename HashArg> struct ListHashSetNodeHashFunctions {
-        typedef ListHashSetNode<ValueArg> Node;
+    template<typename ValueArg, size_t inlineCapacity, typename HashArg> struct ListHashSetNodeHashFunctions {
+        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
         
         static unsigned hash(Node* const& key) { return HashArg::hash(key->m_value); }
         static bool equal(Node* const& a, Node* const& b) { return HashArg::equal(a->m_value, b->m_value); }
         static const bool safeToCompareToEmptyOrDeleted = false;
     };
 
         
         static unsigned hash(Node* const& key) { return HashArg::hash(key->m_value); }
         static bool equal(Node* const& a, Node* const& b) { return HashArg::equal(a->m_value, b->m_value); }
         static const bool safeToCompareToEmptyOrDeleted = false;
     };
 
-    template<typename ValueArg, typename HashArg> class ListHashSetIterator {
+    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator {
     private:
     private:
-        typedef ListHashSet<ValueArg, HashArg> ListHashSetType;
-        typedef ListHashSetIterator<ValueArg, HashArg> iterator;
-        typedef ListHashSetConstIterator<ValueArg, HashArg> const_iterator;
-        typedef ListHashSetNode<ValueArg> Node;
+        typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType;
+        typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator;
+        typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator;
+        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
         typedef ValueArg ValueType;
         typedef ValueType& ReferenceType;
         typedef ValueType* PointerType;
 
         typedef ValueArg ValueType;
         typedef ValueType& ReferenceType;
         typedef ValueType* PointerType;
 
-        friend class ListHashSet<ValueArg, HashArg>;
+        friend class ListHashSet<ValueArg, inlineCapacity, HashArg>;
 
         ListHashSetIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { }
 
 
         ListHashSetIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { }
 
@@ -271,18 +271,18 @@ namespace WTF {
         const_iterator m_iterator;
     };
 
         const_iterator m_iterator;
     };
 
-    template<typename ValueArg, typename HashArg> class ListHashSetConstIterator {
+    template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator {
     private:
     private:
-        typedef ListHashSet<ValueArg, HashArg> ListHashSetType;
-        typedef ListHashSetIterator<ValueArg, HashArg> iterator;
-        typedef ListHashSetConstIterator<ValueArg, HashArg> const_iterator;
-        typedef ListHashSetNode<ValueArg> Node;
+        typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType;
+        typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator;
+        typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator;
+        typedef ListHashSetNode<ValueArg, inlineCapacity> Node;
         typedef ValueArg ValueType;
         typedef const ValueType& ReferenceType;
         typedef const ValueType* PointerType;
 
         typedef ValueArg ValueType;
         typedef const ValueType& ReferenceType;
         typedef const ValueType* PointerType;
 
-        friend class ListHashSet<ValueArg, HashArg>;
-        friend class ListHashSetIterator<ValueArg, HashArg>;
+        friend class ListHashSet<ValueArg, inlineCapacity, HashArg>;
+        friend class ListHashSetIterator<ValueArg, inlineCapacity, HashArg>;
 
         ListHashSetConstIterator(const ListHashSetType* set, Node* position)
             : m_set(set)
 
         ListHashSetConstIterator(const ListHashSetType* set, Node* position)
             : m_set(set)
@@ -341,11 +341,11 @@ namespace WTF {
     };
 
 
     };
 
 
-    template<typename ValueType, typename HashFunctions>
+    template<typename ValueType, size_t inlineCapacity, typename HashFunctions>
     struct ListHashSetTranslator {
     private:
     struct ListHashSetTranslator {
     private:
-        typedef ListHashSetNode<ValueType> Node;
-        typedef ListHashSetNodeAllocator<ValueType> NodeAllocator;
+        typedef ListHashSetNode<ValueType, inlineCapacity> Node;
+        typedef ListHashSetNodeAllocator<ValueType, inlineCapacity> NodeAllocator;
     public:
         static unsigned hash(const ValueType& key) { return HashFunctions::hash(key); }
         static bool equal(Node* const& a, const ValueType& b) { return HashFunctions::equal(a->m_value, b); }
     public:
         static unsigned hash(const ValueType& key) { return HashFunctions::hash(key); }
         static bool equal(Node* const& a, const ValueType& b) { return HashFunctions::equal(a->m_value, b); }
@@ -355,16 +355,16 @@ namespace WTF {
         }
     };
 
         }
     };
 
-    template<typename T, typename U>
-    inline ListHashSet<T, U>::ListHashSet()
+    template<typename T, size_t inlineCapacity, typename U>
+    inline ListHashSet<T, inlineCapacity, U>::ListHashSet()
         : m_head(0)
         , m_tail(0)
         , m_allocator(new NodeAllocator)
     {
     }
 
         : m_head(0)
         , m_tail(0)
         , m_allocator(new NodeAllocator)
     {
     }
 
-    template<typename T, typename U>
-    inline ListHashSet<T, U>::ListHashSet(const ListHashSet& other)
+    template<typename T, size_t inlineCapacity, typename U>
+    inline ListHashSet<T, inlineCapacity, U>::ListHashSet(const ListHashSet& other)
         : m_head(0)
         , m_tail(0)
         , m_allocator(new NodeAllocator)
         : m_head(0)
         , m_tail(0)
         , m_allocator(new NodeAllocator)
@@ -374,16 +374,16 @@ namespace WTF {
             add(*it);
     }
 
             add(*it);
     }
 
-    template<typename T, typename U>
-    inline ListHashSet<T, U>& ListHashSet<T, U>::operator=(const ListHashSet& other)
+    template<typename T, size_t inlineCapacity, typename U>
+    inline ListHashSet<T, inlineCapacity, U>& ListHashSet<T, inlineCapacity, U>::operator=(const ListHashSet& other)
     {
         ListHashSet tmp(other);
         swap(tmp);
         return *this;
     }
 
     {
         ListHashSet tmp(other);
         swap(tmp);
         return *this;
     }
 
-    template<typename T, typename U>
-    inline void ListHashSet<T, U>::swap(ListHashSet& other)
+    template<typename T, size_t inlineCapacity, typename U>
+    inline void ListHashSet<T, inlineCapacity, U>::swap(ListHashSet& other)
     {
         m_impl.swap(other.m_impl);
         std::swap(m_head, other.m_head);
     {
         m_impl.swap(other.m_impl);
         std::swap(m_head, other.m_head);
@@ -391,95 +391,95 @@ namespace WTF {
         m_allocator.swap(other.m_allocator);
     }
 
         m_allocator.swap(other.m_allocator);
     }
 
-    template<typename T, typename U>
-    inline ListHashSet<T, U>::~ListHashSet()
+    template<typename T, size_t inlineCapacity, typename U>
+    inline ListHashSet<T, inlineCapacity, U>::~ListHashSet()
     {
         deleteAllNodes();
     }
 
     {
         deleteAllNodes();
     }
 
-    template<typename T, typename U>
-    inline int ListHashSet<T, U>::size() const
+    template<typename T, size_t inlineCapacity, typename U>
+    inline int ListHashSet<T, inlineCapacity, U>::size() const
     {
         return m_impl.size(); 
     }
 
     {
         return m_impl.size(); 
     }
 
-    template<typename T, typename U>
-    inline int ListHashSet<T, U>::capacity() const
+    template<typename T, size_t inlineCapacity, typename U>
+    inline int ListHashSet<T, inlineCapacity, U>::capacity() const
     {
         return m_impl.capacity(); 
     }
 
     {
         return m_impl.capacity(); 
     }
 
-    template<typename T, typename U>
-    inline bool ListHashSet<T, U>::isEmpty() const
+    template<typename T, size_t inlineCapacity, typename U>
+    inline bool ListHashSet<T, inlineCapacity, U>::isEmpty() const
     {
         return m_impl.isEmpty(); 
     }
 
     {
         return m_impl.isEmpty(); 
     }
 
-    template<typename T, typename U>
-    inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::begin()
+    template<typename T, size_t inlineCapacity, typename U>
+    inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::begin()
     {
         return makeIterator(m_head); 
     }
 
     {
         return makeIterator(m_head); 
     }
 
-    template<typename T, typename U>
-    inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::end()
+    template<typename T, size_t inlineCapacity, typename U>
+    inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::end()
     {
         return makeIterator(0);
     }
 
     {
         return makeIterator(0);
     }
 
-    template<typename T, typename U>
-    inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::begin() const
+    template<typename T, size_t inlineCapacity, typename U>
+    inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::begin() const
     {
         return makeConstIterator(m_head); 
     }
 
     {
         return makeConstIterator(m_head); 
     }
 
-    template<typename T, typename U>
-    inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::end() const
+    template<typename T, size_t inlineCapacity, typename U>
+    inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::end() const
     {
         return makeConstIterator(0); 
     }
 
     {
         return makeConstIterator(0); 
     }
 
-    template<typename T, typename U>
-    inline typename ListHashSet<T, U>::iterator ListHashSet<T, U>::find(const ValueType& value)
+    template<typename T, size_t inlineCapacity, typename U>
+    inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value)
     {
     {
-        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
+        typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator;
         ImplTypeIterator it = m_impl.template find<ValueType, Translator>(value);
         if (it == m_impl.end())
             return end();
         return makeIterator(*it); 
     }
 
         ImplTypeIterator it = m_impl.template find<ValueType, Translator>(value);
         if (it == m_impl.end())
             return end();
         return makeIterator(*it); 
     }
 
-    template<typename T, typename U>
-    inline typename ListHashSet<T, U>::const_iterator ListHashSet<T, U>::find(const ValueType& value) const
+    template<typename T, size_t inlineCapacity, typename U>
+    inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value) const
     {
     {
-        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
+        typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator;
         ImplTypeConstIterator it = m_impl.template find<ValueType, Translator>(value);
         if (it == m_impl.end())
             return end();
         return makeConstIterator(*it);
     }
 
         ImplTypeConstIterator it = m_impl.template find<ValueType, Translator>(value);
         if (it == m_impl.end())
             return end();
         return makeConstIterator(*it);
     }
 
-    template<typename T, typename U>
-    inline bool ListHashSet<T, U>::contains(const ValueType& value) const
+    template<typename T, size_t inlineCapacity, typename U>
+    inline bool ListHashSet<T, inlineCapacity, U>::contains(const ValueType& value) const
     {
     {
-        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
+        typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator;
         return m_impl.template contains<ValueType, Translator>(value);
     }
 
         return m_impl.template contains<ValueType, Translator>(value);
     }
 
-    template<typename T, typename U>
-    pair<typename ListHashSet<T, U>::iterator, bool> ListHashSet<T, U>::add(const ValueType &value)
+    template<typename T, size_t inlineCapacity, typename U>
+    pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::add(const ValueType &value)
     {
     {
-        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
+        typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator;
         pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(value, m_allocator.get());
         if (result.second)
             appendNode(*result.first);
         return std::make_pair(makeIterator(*result.first), result.second);
     }
 
         pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(value, m_allocator.get());
         if (result.second)
             appendNode(*result.first);
         return std::make_pair(makeIterator(*result.first), result.second);
     }
 
-    template<typename T, typename U>
-    pair<typename ListHashSet<T, U>::iterator, bool> ListHashSet<T, U>::insertBefore(iterator it, const ValueType& newValue)
+    template<typename T, size_t inlineCapacity, typename U>
+    pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::insertBefore(iterator it, const ValueType& newValue)
     {
     {
-        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
+        typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator;
         pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(newValue, m_allocator.get());
         if (result.second)
             insertNodeBefore(it.node(), *result.first);
         pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(newValue, m_allocator.get());
         if (result.second)
             insertNodeBefore(it.node(), *result.first);
@@ -487,14 +487,14 @@ namespace WTF {
 
     }
 
 
     }
 
-    template<typename T, typename U>
-    pair<typename ListHashSet<T, U>::iterator, bool> ListHashSet<T, U>::insertBefore(const ValueType& beforeValue, const ValueType& newValue)
+    template<typename T, size_t inlineCapacity, typename U>
+    pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::insertBefore(const ValueType& beforeValue, const ValueType& newValue)
     {
         return insertBefore(find(beforeValue), newValue); 
     }
 
     {
         return insertBefore(find(beforeValue), newValue); 
     }
 
-    template<typename T, typename U>
-    inline void ListHashSet<T, U>::remove(iterator it)
+    template<typename T, size_t inlineCapacity, typename U>
+    inline void ListHashSet<T, inlineCapacity, U>::remove(iterator it)
     {
         if (it == end())
             return;
     {
         if (it == end())
             return;
@@ -502,14 +502,14 @@ namespace WTF {
         unlinkAndDelete(it.node());
     }
 
         unlinkAndDelete(it.node());
     }
 
-    template<typename T, typename U>
-    inline void ListHashSet<T, U>::remove(const ValueType& value)
+    template<typename T, size_t inlineCapacity, typename U>
+    inline void ListHashSet<T, inlineCapacity, U>::remove(const ValueType& value)
     {
         remove(find(value));
     }
 
     {
         remove(find(value));
     }
 
-    template<typename T, typename U>
-    inline void ListHashSet<T, U>::clear()
+    template<typename T, size_t inlineCapacity, typename U>
+    inline void ListHashSet<T, inlineCapacity, U>::clear()
     {
         deleteAllNodes();
         m_impl.clear(); 
     {
         deleteAllNodes();
         m_impl.clear(); 
@@ -517,8 +517,8 @@ namespace WTF {
         m_tail = 0;
     }
 
         m_tail = 0;
     }
 
-    template<typename T, typename U>
-    void ListHashSet<T, U>::unlinkAndDelete(Node* node)
+    template<typename T, size_t inlineCapacity, typename U>
+    void ListHashSet<T, inlineCapacity, U>::unlinkAndDelete(Node* node)
     {
         if (!node->m_prev) {
             ASSERT(node == m_head);
     {
         if (!node->m_prev) {
             ASSERT(node == m_head);
@@ -539,8 +539,8 @@ namespace WTF {
         node->destroy(m_allocator.get());
     }
 
         node->destroy(m_allocator.get());
     }
 
-    template<typename T, typename U>
-    void ListHashSet<T, U>::appendNode(Node* node)
+    template<typename T, size_t inlineCapacity, typename U>
+    void ListHashSet<T, inlineCapacity, U>::appendNode(Node* node)
     {
         node->m_prev = m_tail;
         node->m_next = 0;
     {
         node->m_prev = m_tail;
         node->m_next = 0;
@@ -556,8 +556,8 @@ namespace WTF {
         m_tail = node;
     }
 
         m_tail = node;
     }
 
-    template<typename T, typename U>
-    void ListHashSet<T, U>::insertNodeBefore(Node* beforeNode, Node* newNode)
+    template<typename T, size_t inlineCapacity, typename U>
+    void ListHashSet<T, inlineCapacity, U>::insertNodeBefore(Node* beforeNode, Node* newNode)
     {
         if (!beforeNode)
             return appendNode(newNode);
     {
         if (!beforeNode)
             return appendNode(newNode);
@@ -572,8 +572,8 @@ namespace WTF {
             m_head = newNode;
     }
 
             m_head = newNode;
     }
 
-    template<typename T, typename U>
-    void ListHashSet<T, U>::deleteAllNodes()
+    template<typename T, size_t inlineCapacity, typename U>
+    void ListHashSet<T, inlineCapacity, U>::deleteAllNodes()
     {
         if (!m_head)
             return;
     {
         if (!m_head)
             return;
@@ -582,16 +582,16 @@ namespace WTF {
             node->destroy(m_allocator.get());
     }
 
             node->destroy(m_allocator.get());
     }
 
-    template<typename T, typename U>
-    inline ListHashSetIterator<T, U> ListHashSet<T, U>::makeIterator(Node* position) 
+    template<typename T, size_t inlineCapacity, typename U>
+    inline ListHashSetIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeIterator(Node* position) 
     {
     {
-        return ListHashSetIterator<T, U>(this, position); 
+        return ListHashSetIterator<T, inlineCapacity, U>(this, position); 
     }
 
     }
 
-    template<typename T, typename U>
-    inline ListHashSetConstIterator<T, U> ListHashSet<T, U>::makeConstIterator(Node* position) const
+    template<typename T, size_t inlineCapacity, typename U>
+    inline ListHashSetConstIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeConstIterator(Node* position) const
     { 
     { 
-        return ListHashSetConstIterator<T, U>(this, position); 
+        return ListHashSetConstIterator<T, inlineCapacity, U>(this, position); 
     }
 
     template<bool, typename ValueType, typename HashTableType>
     }
 
     template<bool, typename ValueType, typename HashTableType>
@@ -603,10 +603,10 @@ namespace WTF {
             delete (*it)->m_value;
     }
 
             delete (*it)->m_value;
     }
 
-    template<typename T, typename U>
-    inline void deleteAllValues(const ListHashSet<T, U>& collection)
+    template<typename T, size_t inlineCapacity, typename U>
+    inline void deleteAllValues(const ListHashSet<T, inlineCapacity, U>& collection)
     {
     {
-        deleteAllValues<true, typename ListHashSet<T, U>::ValueType>(collection.m_impl);
+        deleteAllValues<true, typename ListHashSet<T, inlineCapacity, U>::ValueType>(collection.m_impl);
     }
 
 } // namespace WTF
     }
 
 } // namespace WTF
diff --git a/wtf/MD5.cpp b/wtf/MD5.cpp
new file mode 100644 (file)
index 0000000..cd1837a
--- /dev/null
@@ -0,0 +1,304 @@
+// The original file was copied from sqlite, and was in the public domain.
+// Modifications Copyright 2006 Google Inc. All Rights Reserved
+/*
+ * Copyright (C) 2010 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.
+ */
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, construct an
+ * MD5 instance, call addBytes as needed on buffers full of bytes,
+ * and then call checksum, which will fill a supplied 16-byte array
+ * with the digest.
+ */
+
+#include "config.h"
+#include "MD5.h"
+
+#include "Assertions.h"
+#ifndef NDEBUG
+#include "StringExtras.h"
+#include "text/CString.h"
+#endif
+
+namespace WTF {
+
+#ifdef NDEBUG
+static inline void testMD5() { }
+#else
+// MD5 test case.
+static bool isTestMD5Done;
+
+static void expectMD5(CString input, CString expected)
+{
+    MD5 md5;
+    md5.addBytes(reinterpret_cast<const uint8_t*>(input.data()), input.length());
+    Vector<uint8_t, 16> digest = md5.checksum();
+    char* buf = 0;
+    CString actual = CString::newUninitialized(32, buf);
+    for (size_t i = 0; i < 16; i++) {
+        snprintf(buf, 3, "%02x", digest.at(i));
+        buf += 2;
+    }
+    ASSERT_WITH_MESSAGE(actual == expected, "input:%s[%d] actual:%s expected:%s", input.data(), input.length(), actual.data(), expected.data());
+}
+
+static void testMD5()
+{
+    if (isTestMD5Done)
+        return;
+    isTestMD5Done = true;
+
+    // MD5 Test suite from http://www.ietf.org/rfc/rfc1321.txt
+    expectMD5("", "d41d8cd98f00b204e9800998ecf8427e");
+    expectMD5("a", "0cc175b9c0f1b6a831c399e269772661");
+    expectMD5("abc", "900150983cd24fb0d6963f7d28e17f72");
+    expectMD5("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
+    expectMD5("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
+    expectMD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d174ab98d277d9f5a5611c2c9f419d9f");
+    expectMD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a");
+}
+#endif
+
+// Note: this code is harmless on little-endian machines.
+
+static void reverseBytes(uint8_t* buf, unsigned longs)
+{
+    ASSERT(longs > 0);
+    do {
+        uint32_t t = static_cast<uint32_t>(buf[3] << 8 | buf[2]) << 16 | buf[1] << 8 | buf[0];
+        ASSERT_WITH_MESSAGE(!(reinterpret_cast<uintptr_t>(buf) % sizeof(t)), "alignment error of buf");
+        *reinterpret_cast<uint32_t *>(buf) = t;
+        buf += 4;
+    } while (--longs);
+}
+
+// The four core functions.
+// F1 is originally defined as (x & y | ~x & z), but optimized somewhat: 4 bit ops -> 3 bit ops.
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+// This is the central step in the MD5 algorithm.
+#define MD5STEP(f, w, x, y, z, data, s) \
+    (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
+
+static void MD5Transform(uint32_t buf[4], const uint32_t in[16])
+{
+    uint32_t a = buf[0];
+    uint32_t b = buf[1];
+    uint32_t c = buf[2];
+    uint32_t d = buf[3];
+
+    MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
+    MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
+    MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
+    MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
+    MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
+    MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
+    MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
+    MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
+    MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
+    MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
+    MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
+    MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
+    MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
+    MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
+    MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
+    MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
+
+    MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
+    MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
+    MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
+    MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
+    MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
+    MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
+    MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
+    MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
+    MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
+    MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
+    MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
+    MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
+    MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
+    MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
+    MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
+    MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
+
+    MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
+    MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
+    MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
+    MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
+    MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
+    MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
+    MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
+    MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
+    MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
+    MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
+    MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
+    MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
+    MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
+    MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
+    MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
+    MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
+
+    MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
+    MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
+    MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
+    MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
+    MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
+    MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
+    MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
+    MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
+    MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
+    MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
+    MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
+    MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
+    MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
+    MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
+    MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
+    MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
+
+    buf[0] += a;
+    buf[1] += b;
+    buf[2] += c;
+    buf[3] += d;
+}
+
+MD5::MD5()
+{
+    testMD5();
+    m_buf[0] = 0x67452301;
+    m_buf[1] = 0xefcdab89;
+    m_buf[2] = 0x98badcfe;
+    m_buf[3] = 0x10325476;
+    m_bits[0] = 0;
+    m_bits[1] = 0;
+    memset(m_in, 0, sizeof(m_in));
+    ASSERT_WITH_MESSAGE(!(reinterpret_cast<uintptr_t>(m_in) % sizeof(uint32_t)), "alignment error of m_in");
+}
+
+void MD5::addBytes(const uint8_t* input, size_t length)
+{
+    const uint8_t* buf = input;
+
+    // Update bitcount
+    uint32_t t = m_bits[0];
+    m_bits[0] = t + (length << 3);
+    if (m_bits[0] < t)
+        m_bits[1]++; // Carry from low to high
+    m_bits[1] += length >> 29;
+
+    t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data
+
+    // Handle any leading odd-sized chunks
+
+    if (t) {
+        uint8_t* p = m_in + t;
+
+        t = 64 - t;
+        if (length < t) {
+            memcpy(p, buf, length);
+            return;
+        }
+        memcpy(p, buf, t);
+        reverseBytes(m_in, 16);
+        MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in)); // m_in is 4-byte aligned.
+        buf += t;
+        length -= t;
+    }
+
+    // Process data in 64-byte chunks
+
+    while (length >= 64) {
+        memcpy(m_in, buf, 64);
+        reverseBytes(m_in, 16);
+        MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in)); // m_in is 4-byte aligned.
+        buf += 64;
+        length -= 64;
+    }
+
+    // Handle any remaining bytes of data.
+    memcpy(m_in, buf, length);
+}
+
+Vector<uint8_t, 16> MD5::checksum()
+{
+    // Compute number of bytes mod 64
+    unsigned count = (m_bits[0] >> 3) & 0x3F;
+
+    // Set the first char of padding to 0x80.  This is safe since there is
+    // always at least one byte free
+    uint8_t* p = m_in + count;
+    *p++ = 0x80;
+
+    // Bytes of padding needed to make 64 bytes
+    count = 64 - 1 - count;
+
+    // Pad out to 56 mod 64
+    if (count < 8) {
+        // Two lots of padding:  Pad the first block to 64 bytes
+        memset(p, 0, count);
+        reverseBytes(m_in, 16);
+        MD5Transform(m_buf, reinterpret_cast<uint32_t *>(m_in)); // m_in is 4-byte aligned.
+
+        // Now fill the next block with 56 bytes
+        memset(m_in, 0, 56);
+    } else {
+        // Pad block to 56 bytes
+        memset(p, 0, count - 8);
+    }
+    reverseBytes(m_in, 14);
+
+    // Append length in bits and transform
+    // m_in is 4-byte aligned.
+    (reinterpret_cast<uint32_t*>(m_in))[14] = m_bits[0];
+    (reinterpret_cast<uint32_t*>(m_in))[15] = m_bits[1];
+
+    MD5Transform(m_buf, reinterpret_cast<uint32_t*>(m_in));
+    reverseBytes(reinterpret_cast<uint8_t*>(m_buf), 4);
+    Vector<uint8_t, 16> digest;
+    digest.append(reinterpret_cast<uint8_t*>(m_buf), 16);
+
+    // In case it's sensitive
+    memset(m_buf, 0, sizeof(m_buf));
+    memset(m_bits, 0, sizeof(m_bits));
+    memset(m_in, 0, sizeof(m_in));
+    return digest;
+}
+
+} // namespace WTF
diff --git a/wtf/MD5.h b/wtf/MD5.h
new file mode 100644 (file)
index 0000000..8ebfc45
--- /dev/null
+++ b/wtf/MD5.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 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 WTF_MD5_h
+#define WTF_MD5_h
+
+#include <wtf/Vector.h>
+
+namespace WTF {
+
+class MD5 {
+public:
+    MD5();
+
+    void addBytes(const Vector<uint8_t>& input)
+    {
+        addBytes(input.data(), input.size());
+    }
+    void addBytes(const uint8_t* input, size_t length);
+
+    // checksum has a side effect of resetting the state of the object.
+    Vector<uint8_t, 16> checksum();
+
+private:
+    uint32_t m_buf[4];
+    uint32_t m_bits[2];
+    uint8_t m_in[64];
+};
+
+} // namespace WTF
+
+using WTF::MD5;
+
+#endif // WTF_MD5_h
index 40a4ae530818ea30d973afce7127f6e2000f7d91..1a0682bb6b60c267b40319c3aa6e40cbdb86579d 100644 (file)
 #include "config.h"
 #include "MainThread.h"
 
 #include "config.h"
 #include "MainThread.h"
 
-#include "StdLibExtras.h"
 #include "CurrentTime.h"
 #include "Deque.h"
 #include "CurrentTime.h"
 #include "Deque.h"
+#include "StdLibExtras.h"
 #include "Threading.h"
 
 #include "Threading.h"
 
+#if PLATFORM(CHROMIUM)
+#error Chromium uses a different main thread implementation
+#endif
+
 namespace WTF {
 
 struct FunctionWithContext {
 namespace WTF {
 
 struct FunctionWithContext {
@@ -47,13 +51,30 @@ struct FunctionWithContext {
         , syncFlag(syncFlag)
     { 
     }
         , syncFlag(syncFlag)
     { 
     }
+    bool operator == (const FunctionWithContext& o)
+    {
+        return function == o.function
+            && context == o.context
+            && syncFlag == o.syncFlag;
+    }
 };
 
 };
 
+class FunctionWithContextFinder {
+public:
+    FunctionWithContextFinder(const FunctionWithContext& m) : m(m) {}
+    bool operator() (FunctionWithContext& o) { return o == m; }
+    FunctionWithContext m;
+};
+
+
 typedef Deque<FunctionWithContext> FunctionQueue;
 
 static bool callbacksPaused; // This global variable is only accessed from main thread.
 typedef Deque<FunctionWithContext> FunctionQueue;
 
 static bool callbacksPaused; // This global variable is only accessed from main thread.
+#if !PLATFORM(MAC) && !PLATFORM(QT)
+static ThreadIdentifier mainThreadIdentifier;
+#endif
 
 
-Mutex& mainThreadFunctionQueueMutex()
+static Mutex& mainThreadFunctionQueueMutex()
 {
     DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
     return staticMutex;
 {
     DEFINE_STATIC_LOCAL(Mutex, staticMutex, ());
     return staticMutex;
@@ -65,12 +86,51 @@ static FunctionQueue& functionQueue()
     return staticFunctionQueue;
 }
 
     return staticFunctionQueue;
 }
 
+
+#if !PLATFORM(MAC)
+
 void initializeMainThread()
 void initializeMainThread()
+{
+    static bool initializedMainThread;
+    if (initializedMainThread)
+        return;
+    initializedMainThread = true;
+
+#if !PLATFORM(QT)
+    mainThreadIdentifier = currentThread();
+#endif
+
+    mainThreadFunctionQueueMutex();
+    initializeMainThreadPlatform();
+}
+
+#else
+
+static pthread_once_t initializeMainThreadKeyOnce = PTHREAD_ONCE_INIT;
+
+static void initializeMainThreadOnce()
 {
     mainThreadFunctionQueueMutex();
     initializeMainThreadPlatform();
 }
 
 {
     mainThreadFunctionQueueMutex();
     initializeMainThreadPlatform();
 }
 
+void initializeMainThread()
+{
+    pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadOnce);
+}
+
+static void initializeMainThreadToProcessMainThreadOnce()
+{
+    mainThreadFunctionQueueMutex();
+    initializeMainThreadToProcessMainThreadPlatform();
+}
+
+void initializeMainThreadToProcessMainThread()
+{
+    pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadToProcessMainThreadOnce);
+}
+#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;
 
 // 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;
 
@@ -139,6 +199,24 @@ void callOnMainThreadAndWait(MainThreadFunction* function, void* context)
     syncFlag.wait(functionQueueMutex);
 }
 
     syncFlag.wait(functionQueueMutex);
 }
 
+void cancelCallOnMainThread(MainThreadFunction* function, void* context)
+{
+    ASSERT(function);
+
+    MutexLocker locker(mainThreadFunctionQueueMutex());
+
+    FunctionWithContextFinder pred(FunctionWithContext(function, context));
+
+    while (true) {
+        // We must redefine 'i' each pass, because the itererator's operator= 
+        // requires 'this' to be valid, and remove() invalidates all iterators
+        FunctionQueue::iterator i(functionQueue().findIf(pred));
+        if (i == functionQueue().end())
+            break;
+        functionQueue().remove(i);
+    }
+}
+
 void setMainThreadCallbacksPaused(bool paused)
 {
     ASSERT(isMainThread());
 void setMainThreadCallbacksPaused(bool paused)
 {
     ASSERT(isMainThread());
@@ -152,4 +230,11 @@ void setMainThreadCallbacksPaused(bool paused)
         scheduleDispatchFunctionsOnMainThread();
 }
 
         scheduleDispatchFunctionsOnMainThread();
 }
 
+#if !PLATFORM(MAC) && !PLATFORM(QT)
+bool isMainThread()
+{
+    return currentThread() == mainThreadIdentifier;
+}
+#endif
+
 } // namespace WTF
 } // namespace WTF
index 8c0275bac6377779f5fbe88d3c4e3dc8684946af..157e2cc794c19ab7be00145c2870712ea6b2a348 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.
  * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
  *
  * Redistribution and use in source and binary forms, with or without
  * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
  *
  * Redistribution and use in source and binary forms, with or without
 #ifndef MainThread_h
 #define MainThread_h
 
 #ifndef MainThread_h
 #define MainThread_h
 
-namespace WTF {
+#include <stdint.h>
 
 
-class Mutex;
+namespace WTF {
 
 
+typedef uint32_t ThreadIdentifier;
 typedef void MainThreadFunction(void*);
 
 typedef void MainThreadFunction(void*);
 
-void callOnMainThread(MainThreadFunction*, void* context);
+// Must be called from the main thread.
+void initializeMainThread();
 
 
-// Blocks the thread until the call finishes on the main thread. Misusing this can easily cause deadlocks.
+void callOnMainThread(MainThreadFunction*, void* context);
 void callOnMainThreadAndWait(MainThreadFunction*, void* context);
 void callOnMainThreadAndWait(MainThreadFunction*, void* context);
+void cancelCallOnMainThread(MainThreadFunction*, void* context);
 
 void setMainThreadCallbacksPaused(bool paused);
 
 
 void setMainThreadCallbacksPaused(bool paused);
 
-// Must be called from the main thread (Darwin is an exception to this rule).
-void initializeMainThread();
+bool isMainThread();
+bool isWebThread();
 
 
-// These functions are internal to the callOnMainThread implementation.
+// NOTE: these functions are internal to the callOnMainThread implementation.
 void initializeMainThreadPlatform();
 void scheduleDispatchFunctionsOnMainThread();
 void initializeMainThreadPlatform();
 void scheduleDispatchFunctionsOnMainThread();
-Mutex& mainThreadFunctionQueueMutex();
 void dispatchFunctionsFromMainThread();
 
 void dispatchFunctionsFromMainThread();
 
+#if PLATFORM(MAC)
+// This version of initializeMainThread sets up the main thread as corresponding
+// to the process's main thread, and not necessarily the thread that calls this
+// function. It should only be used as a legacy aid for Mac WebKit.
+void initializeMainThreadToProcessMainThread();
+void initializeMainThreadToProcessMainThreadPlatform();
+#endif
+
 } // namespace WTF
 
 using WTF::callOnMainThread;
 using WTF::callOnMainThreadAndWait;
 } // namespace WTF
 
 using WTF::callOnMainThread;
 using WTF::callOnMainThreadAndWait;
+using WTF::cancelCallOnMainThread;
 using WTF::setMainThreadCallbacksPaused;
 using WTF::setMainThreadCallbacksPaused;
-
+using WTF::isMainThread;
 #endif // MainThread_h
 #endif // MainThread_h
index 9ea57fd771b54585ba3ef98ca530559936e21c5b..1f77b61364459a94cf509840a6548c4560c62eda 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,8 +26,8 @@
 #ifndef WTF_MathExtras_h
 #define WTF_MathExtras_h
 
 #ifndef WTF_MathExtras_h
 #define WTF_MathExtras_h
 
+#include <cmath>
 #include <float.h>
 #include <float.h>
-#include <math.h>
 #include <stdlib.h>
 
 #if OS(SOLARIS)
 #include <stdlib.h>
 
 #if OS(SOLARIS)
@@ -98,17 +98,34 @@ inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x
 
 #if COMPILER(MSVC) || COMPILER(RVCT)
 
 
 #if COMPILER(MSVC) || COMPILER(RVCT)
 
-inline long long llround(double num) { return static_cast<long long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); }
-inline long long llroundf(float num) { return static_cast<long long>(num > 0 ? num + 0.5f : ceil(num - 0.5f)); }
-inline long lround(double num) { return static_cast<long>(num > 0 ? num + 0.5 : ceil(num - 0.5)); }
-inline long lroundf(float num) { return static_cast<long>(num > 0 ? num + 0.5f : ceilf(num - 0.5f)); }
-inline double round(double num) { return num > 0 ? floor(num + 0.5) : ceil(num - 0.5); }
-inline float roundf(float num) { return num > 0 ? floorf(num + 0.5f) : ceilf(num - 0.5f); }
+// We must not do 'num + 0.5' or 'num - 0.5' because they can cause precision loss.
+static double round(double num)
+{
+    double integer = ceil(num);
+    if (num > 0)
+        return integer - num > 0.5 ? integer - 1.0 : integer;
+    return integer - num >= 0.5 ? integer - 1.0 : integer;
+}
+static float roundf(float num)
+{
+    float integer = ceilf(num);
+    if (num > 0)
+        return integer - num > 0.5f ? integer - 1.0f : integer;
+    return integer - num >= 0.5f ? integer - 1.0f : integer;
+}
+inline long long llround(double num) { return static_cast<long long>(round(num)); }
+inline long long llroundf(float num) { return static_cast<long long>(roundf(num)); }
+inline long lround(double num) { return static_cast<long>(round(num)); }
+inline long lroundf(float num) { return static_cast<long>(roundf(num)); }
 inline double trunc(double num) { return num > 0 ? floor(num) : ceil(num); }
 
 #endif
 
 #if COMPILER(MSVC)
 inline double trunc(double num) { return num > 0 ? floor(num) : ceil(num); }
 
 #endif
 
 #if COMPILER(MSVC)
+// The 64bit version of abs() is already defined in stdlib.h which comes with VC10
+#if COMPILER(MSVC9_OR_LOWER)
+inline long long abs(long long num) { return _abs64(num); }
+#endif
 
 inline bool isinf(double num) { return !_finite(num) && !_isnan(num); }
 inline bool isnan(double num) { return !!_isnan(num); }
 
 inline bool isinf(double num) { return !_finite(num) && !_isnan(num); }
 inline bool isnan(double num) { return !!_isnan(num); }
@@ -173,4 +190,11 @@ inline float deg2turn(float d) { return d / 360.0f; }
 inline float rad2grad(float r) { return r * 200.0f / piFloat; }
 inline float grad2rad(float g) { return g * piFloat / 200.0f; }
 
 inline float rad2grad(float r) { return r * 200.0f / piFloat; }
 inline float grad2rad(float g) { return g * piFloat / 200.0f; }
 
+#if !COMPILER(MSVC) && !COMPILER(WINSCW) && !(COMPILER(RVCT) && OS(SYMBIAN))
+using std::isfinite;
+using std::isinf;
+using std::isnan;
+using std::signbit;
+#endif
+
 #endif // #ifndef WTF_MathExtras_h
 #endif // #ifndef WTF_MathExtras_h
index c88235a8a9407ce780f045bba1e227a72ef8b83f..8b6cbf45e7acd24831843d1c734266b985407ea9 100644 (file)
@@ -35,7 +35,7 @@ namespace WTF {
 
         ~OwnFastMallocPtr()
         {
 
         ~OwnFastMallocPtr()
         {
-            fastFree(m_ptr);
+            fastFree(const_cast<void*>(static_cast<const void*>(const_cast<const T*>(m_ptr))));
         }
 
         T* get() const { return m_ptr; }
         }
 
         T* get() const { return m_ptr; }
index b7e62b1eab130ea41b67505a4318009a6c76c2b9..af1684bddb1423389e73ef2bb7fb7fc2b41befcd 100644 (file)
@@ -40,7 +40,6 @@ namespace WTF {
         typedef ValueType* PtrType;
 
         explicit OwnPtr(PtrType ptr = 0) : m_ptr(ptr) { }
         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);
 
         // See comment in PassOwnPtr.h for why this takes a const reference.
         template <typename U> OwnPtr(const PassOwnPtr<U>& o);
 
@@ -58,8 +57,6 @@ namespace WTF {
         // FIXME: This should be renamed to adopt. 
         void set(PtrType ptr) { ASSERT(!ptr || m_ptr != ptr); deleteOwnedPtr(m_ptr); m_ptr = ptr; }
 
         // FIXME: This should be renamed to adopt. 
         void set(PtrType ptr) { ASSERT(!ptr || m_ptr != ptr); deleteOwnedPtr(m_ptr); m_ptr = ptr; }
 
-        void adopt(std::auto_ptr<ValueType> autoPtr) { ASSERT(!autoPtr.get() || m_ptr != autoPtr.get()); deleteOwnedPtr(m_ptr); m_ptr = autoPtr.release(); }
-
         void clear() { deleteOwnedPtr(m_ptr); m_ptr = 0; }
 
         ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
         void clear() { deleteOwnedPtr(m_ptr); m_ptr = 0; }
 
         ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; }
index 6d91a54b9edc10c349b9e83dded167e24e7a4879..c59fdc51e4cd21a2e5c672d12123261d6f049545 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2009 Apple Inc. All rights reserved.
  * Copyright (C) 2009 Torch Mobile, Inc.
 /*
  * Copyright (C) 2009 Apple Inc. All rights reserved.
  * Copyright (C) 2009 Torch Mobile, Inc.
+ * Copyright (C) 2010 Company 100 Inc.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,6 +38,14 @@ typedef struct HPEN__* HPEN;
 typedef struct HRGN__* HRGN;
 #endif
 
 typedef struct HRGN__* HRGN;
 #endif
 
+#if PLATFORM(BREWMP)
+// Forward delcarations at this point avoid the need to include BREW includes
+// in WTF headers.
+typedef struct _IFileMgr IFileMgr;
+typedef struct _IFile IFile;
+typedef struct IBitmap IBitmap;
+#endif
+
 namespace WTF {
 
     template <typename T> inline void deleteOwnedPtr(T* ptr)
 namespace WTF {
 
     template <typename T> inline void deleteOwnedPtr(T* ptr)
@@ -56,6 +65,12 @@ namespace WTF {
     void deleteOwnedPtr(HRGN);
 #endif
 
     void deleteOwnedPtr(HRGN);
 #endif
 
+#if PLATFORM(BREWMP)
+    void deleteOwnedPtr(IFileMgr*);
+    void deleteOwnedPtr(IFile*);
+    void deleteOwnedPtr(IBitmap*);
+#endif
+
 } // namespace WTF
 
 #endif // WTF_OwnPtrCommon_h
 } // namespace WTF
 
 #endif // WTF_OwnPtrCommon_h
diff --git a/wtf/OwnPtrWin.cpp b/wtf/OwnPtrWin.cpp
deleted file mode 100644 (file)
index 67a32ff..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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
- * 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 COMPUTER, 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 COMPUTER, 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 "OwnPtr.h"
-
-#include <windows.h>
-
-namespace WTF {
-
-void deleteOwnedPtr(HBITMAP ptr)
-{
-    if (ptr)
-        DeleteObject(ptr);
-}
-
-void deleteOwnedPtr(HBRUSH ptr)
-{
-    if (ptr)
-        DeleteObject(ptr);
-}
-
-void deleteOwnedPtr(HDC ptr)
-{
-    if (ptr)
-        DeleteDC(ptr);
-}
-
-void deleteOwnedPtr(HFONT ptr)
-{
-    if (ptr)
-        DeleteObject(ptr);
-}
-
-void deleteOwnedPtr(HPALETTE ptr)
-{
-    if (ptr)
-        DeleteObject(ptr);
-}
-
-void deleteOwnedPtr(HPEN ptr)
-{
-    if (ptr)
-        DeleteObject(ptr);
-}
-
-void deleteOwnedPtr(HRGN ptr)
-{
-    if (ptr)
-        DeleteObject(ptr);
-}
-
-}
index 36ba78e168f9ab6aa83f3a354f3280d0965d68b4..25a93a4351e084ea7b651aad1e680ba1e83ac62e 100644 (file)
@@ -28,24 +28,48 @@ namespace WTF {
     template<typename T> class RefPtr;
     template<typename T> class PassRefPtr;
     template <typename T> PassRefPtr<T> adoptRef(T*);
     template<typename T> class RefPtr;
     template<typename T> class PassRefPtr;
     template <typename T> PassRefPtr<T> adoptRef(T*);
-    
-    // Remove inline for winscw compiler to prevent the compiler agressively resolving 
-    // T::deref(), which will fail compiling when PassRefPtr<T> is used as class member 
-    // or function arguments before T is defined.
+
+
+    // Remove inline for WINSCW compiler to prevent the compiler agressively resolving
+    // T::ref() and T::deref(), which will fail compiling when PassRefPtr<T> is used as
+    // a class member or function arguments before T is defined.
+
+    // [Qt]r57240 broke Qt build (might be a gcc bug)
+    // FIXME! See: https://bugs.webkit.org/show_bug.cgi?id=37253
+    template<typename T>
+#if !COMPILER(WINSCW)
+#if !PLATFORM(QT)
+    ALWAYS_INLINE
+#else
+    inline
+#endif
+#endif
+    void refIfNotNull(T* ptr)
+    {
+        if (LIKELY(ptr != 0))
+            ptr->ref();
+    }
+
+    // [Qt]r57240 broke Qt build (might be a gcc bug)
+    // FIXME! See: https://bugs.webkit.org/show_bug.cgi?id=37253
     template<typename T> 
 #if !COMPILER(WINSCW)
     template<typename T> 
 #if !COMPILER(WINSCW)
-    inline 
+#if !PLATFORM(QT)
+    ALWAYS_INLINE
+#else
+    inline
+#endif
 #endif
     void derefIfNotNull(T* ptr)
     {
 #endif
     void derefIfNotNull(T* ptr)
     {
-        if (UNLIKELY(ptr != 0))
+        if (LIKELY(ptr != 0))
             ptr->deref();
     }
 
     template<typename T> class PassRefPtr {
     public:
         PassRefPtr() : m_ptr(0) {}
             ptr->deref();
     }
 
     template<typename T> class PassRefPtr {
     public:
         PassRefPtr() : m_ptr(0) {}
-        PassRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
+        PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
         // It somewhat breaks the type system to allow transfer of ownership out of
         // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
         // temporaries, and we don't really have a need to use real const PassRefPtrs 
         // It somewhat breaks the type system to allow transfer of ownership out of
         // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr
         // temporaries, and we don't really have a need to use real const PassRefPtrs 
@@ -53,14 +77,14 @@ namespace WTF {
         PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
         template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
 
         PassRefPtr(const PassRefPtr& o) : m_ptr(o.releaseRef()) {}
         template <typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.releaseRef()) { }
 
-        ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull<T>(m_ptr); }
+        ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); }
 
         template <class U> 
 
         template <class U> 
-        PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
+        PassRefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); }
         
         T* get() const { return m_ptr; }
 
         
         T* get() const { return m_ptr; }
 
-        void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
+        void clear() { T* ptr = m_ptr; derefIfNotNull(ptr); m_ptr = 0; }
         T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
 
         T& operator*() const { return *m_ptr; }
         T* releaseRef() const { T* tmp = m_ptr; m_ptr = 0; return tmp; }
 
         T& operator*() const { return *m_ptr; }
@@ -143,23 +167,19 @@ namespace WTF {
     template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) 
     {
         T* optr = o.get();
     template <typename T> template <typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) 
     {
         T* optr = o.get();
-        if (optr)
-            optr->ref();
+        refIfNotNull(optr);
         T* ptr = m_ptr;
         m_ptr = optr;
         T* ptr = m_ptr;
         m_ptr = optr;
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
     
     template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
     {
         return *this;
     }
     
     template <typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr)
     {
-        if (optr)
-            optr->ref();
+        refIfNotNull(optr);
         T* ptr = m_ptr;
         m_ptr = optr;
         T* ptr = m_ptr;
         m_ptr = optr;
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
 
         return *this;
     }
 
@@ -167,8 +187,7 @@ namespace WTF {
     {
         T* ptr = m_ptr;
         m_ptr = ref.releaseRef();
     {
         T* ptr = m_ptr;
         m_ptr = ref.releaseRef();
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
     
         return *this;
     }
     
@@ -176,8 +195,7 @@ namespace WTF {
     {
         T* ptr = m_ptr;
         m_ptr = ref.releaseRef();
     {
         T* ptr = m_ptr;
         m_ptr = ref.releaseRef();
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
     
         return *this;
     }
     
index cf6c86355520cfc7fbdbf3c79ddfbd82c80e1ece..621f0f2fe1d829d3e79f8e6388e76bd24c5b0831 100644 (file)
 /* ==== COMPILER() - the compiler being used to build the project ==== */
 
 /* COMPILER(MSVC) Microsoft Visual C++ */
 /* ==== COMPILER() - the compiler being used to build the project ==== */
 
 /* COMPILER(MSVC) Microsoft Visual C++ */
-/* COMPILER(MSVC7) Microsoft Visual C++ v7 or lower*/
+/* COMPILER(MSVC7_OR_LOWER) Microsoft Visual C++ 2003 or lower*/
+/* COMPILER(MSVC9_OR_LOWER) Microsoft Visual C++ 2008 or lower*/
 #if defined(_MSC_VER)
 #define WTF_COMPILER_MSVC 1
 #if _MSC_VER < 1400
 #if defined(_MSC_VER)
 #define WTF_COMPILER_MSVC 1
 #if _MSC_VER < 1400
-#define WTF_COMPILER_MSVC7 1
+#define WTF_COMPILER_MSVC7_OR_LOWER 1
+#elif _MSC_VER < 1600
+#define WTF_COMPILER_MSVC9_OR_LOWER 1
 #endif
 #endif
 
 #endif
 #endif
 
 #endif
 
 /* COMPILER(MINGW) - MinGW GCC */
 #endif
 
 /* COMPILER(MINGW) - MinGW GCC */
-#if defined(MINGW) || defined(__MINGW32__)
+/* COMPILER(MINGW64) - mingw-w64 GCC - only used as additional check to exclude mingw.org specific functions */
+#if defined(__MINGW32__)
 #define WTF_COMPILER_MINGW 1
 #define WTF_COMPILER_MINGW 1
-#endif
+#include <_mingw.h> /* private MinGW header */
+    #if defined(__MINGW64_VERSION_MAJOR) /* best way to check for mingw-w64 vs mingw.org */
+        #define WTF_COMPILER_MINGW64 1
+    #endif /* __MINGW64_VERSION_MAJOR */
+#endif /* __MINGW32__ */
 
 /* COMPILER(WINSCW) - CodeWarrior for Symbian emulator */
 #if defined(__WINSCW__)
 #define WTF_COMPILER_WINSCW 1
 
 /* COMPILER(WINSCW) - CodeWarrior for Symbian emulator */
 #if defined(__WINSCW__)
 #define WTF_COMPILER_WINSCW 1
+/* cross-compiling, it is not really windows */
+#undef WIN32
+#undef _WIN32
 #endif
 
 
 #endif
 
 
 /* CPU(IA64) - Itanium / IA-64 */
 #if defined(__ia64__)
 #define WTF_CPU_IA64 1
 /* CPU(IA64) - Itanium / IA-64 */
 #if defined(__ia64__)
 #define WTF_CPU_IA64 1
+/* 32-bit mode on Itanium */
+#if !defined(__LP64__)
+#define WTF_CPU_IA64_32 1
+#endif
+#endif
+
+/* CPU(MIPS) - MIPS 32-bit */
+/* Note: Only O32 ABI is tested, so we enable it for O32 ABI for now.  */
+#if (defined(mips) || defined(__mips__)) \
+    && defined(_ABIO32)
+#define WTF_CPU_MIPS 1
+#if defined(__MIPSEB__)
+#define WTF_CPU_BIG_ENDIAN 1
 #endif
 #endif
+#define WTF_MIPS_PIC (defined __PIC__)
+#define WTF_MIPS_ARCH __mips
+#define WTF_MIPS_ISA(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH == v)
+#define WTF_MIPS_ISA_AT_LEAST(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH >= v)
+#define WTF_MIPS_ARCH_REV __mips_isa_rev
+#define WTF_MIPS_ISA_REV(v) (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == v)
+#define WTF_MIPS_DOUBLE_FLOAT (defined __mips_hard_float && !defined __mips_single_float)
+#endif /* MIPS */
 
 /* CPU(PPC) - PowerPC 32-bit */
 #if   defined(__ppc__)     \
 
 /* CPU(PPC) - PowerPC 32-bit */
 #if   defined(__ppc__)     \
 
 /* CPU(SPARC) - any SPARC, true for CPU(SPARC32) and CPU(SPARC64) */
 #if CPU(SPARC32) || CPU(SPARC64)
 
 /* CPU(SPARC) - any SPARC, true for CPU(SPARC32) and CPU(SPARC64) */
 #if CPU(SPARC32) || CPU(SPARC64)
-#define WTF_CPU_SPARC
+#define WTF_CPU_SPARC 1
 #endif
 
 /* CPU(X86) - i386 / x86 32-bit */
 #endif
 
 /* CPU(X86) - i386 / x86 32-bit */
 
 /* CPU(ARM) - ARM, any version*/
 #if   defined(arm) \
 
 /* CPU(ARM) - ARM, any version*/
 #if   defined(arm) \
-    || defined(__arm__)
+    || defined(__arm__) \
+    || defined(ARM) \
+    || defined(_ARM_)
 #define WTF_CPU_ARM 1
 
 #if defined(__ARMEB__)
 #define WTF_CPU_ARM 1
 
 #if defined(__ARMEB__)
 #elif !defined(__ARM_EABI__) \
     && !defined(__EABI__) \
     && !defined(__VFP_FP__) \
 #elif !defined(__ARM_EABI__) \
     && !defined(__EABI__) \
     && !defined(__VFP_FP__) \
+    && !defined(_WIN32_WCE) \
     && !defined(ANDROID)
 #define WTF_CPU_MIDDLE_ENDIAN 1
 
     && !defined(ANDROID)
 #define WTF_CPU_MIDDLE_ENDIAN 1
 
 
 /* OS(SYMBIAN) - Symbian */
 #if defined (__SYMBIAN32__)
 
 /* OS(SYMBIAN) - Symbian */
 #if defined (__SYMBIAN32__)
-/* we are cross-compiling, it is not really windows */
-#undef WTF_OS_WINDOWS
-#undef WTF_PLATFORM_WIN
 #define WTF_OS_SYMBIAN 1
 #endif
 
 #define WTF_OS_SYMBIAN 1
 #endif
 
 #define WTF_PLATFORM_GTK 1
 #elif defined(BUILDING_HAIKU__)
 #define WTF_PLATFORM_HAIKU 1
 #define WTF_PLATFORM_GTK 1
 #elif defined(BUILDING_HAIKU__)
 #define WTF_PLATFORM_HAIKU 1
+#elif defined(BUILDING_BREWMP__)
+#define WTF_PLATFORM_BREWMP 1
+#if defined(AEE_SIMULATOR)
+#define WTF_PLATFORM_BREWMP_SIMULATOR 1
+#else
+#define WTF_PLATFORM_BREWMP_SIMULATOR 0
+#endif
+#undef WTF_OS_WINDOWS
+#undef WTF_PLATFORM_WIN
 #elif OS(DARWIN)
 #define WTF_PLATFORM_MAC 1
 #elif OS(WINDOWS)
 #elif OS(DARWIN)
 #define WTF_PLATFORM_MAC 1
 #elif OS(WINDOWS)
 */
 #if OS(WINCE) && PLATFORM(QT)
 #   include <QtGlobal>
 */
 #if OS(WINCE) && PLATFORM(QT)
 #   include <QtGlobal>
-#   undef WTF_PLATFORM_BIG_ENDIAN
-#   undef WTF_PLATFORM_MIDDLE_ENDIAN
-#   if Q_BYTE_ORDER == Q_BIG_EDIAN
-#       define WTF_PLATFORM_BIG_ENDIAN 1
+#   undef WTF_CPU_BIG_ENDIAN
+#   undef WTF_CPU_MIDDLE_ENDIAN
+#   if Q_BYTE_ORDER == Q_BIG_ENDIAN
+#       define WTF_CPU_BIG_ENDIAN 1
 #   endif
 
 #   include <ce_time.h>
 #   endif
 
 #   include <ce_time.h>
 
 #if PLATFORM(QT)
 #define WTF_USE_QT4_UNICODE 1
 
 #if PLATFORM(QT)
 #define WTF_USE_QT4_UNICODE 1
+#if !defined(ENABLE_WIDGETS_10_SUPPORT)
+#define ENABLE_WIDGETS_10_SUPPORT 1
+#endif
 #elif OS(WINCE)
 #define WTF_USE_WINCE_UNICODE 1
 #elif PLATFORM(GTK)
 #elif OS(WINCE)
 #define WTF_USE_WINCE_UNICODE 1
 #elif PLATFORM(GTK)
 #endif
 
 
 #endif
 
 
+
 #if PLATFORM(CHROMIUM) && OS(DARWIN)
 #define WTF_PLATFORM_CF 1
 #define WTF_USE_PTHREADS 1
 #define HAVE_PTHREAD_RWLOCK 1
 #if PLATFORM(CHROMIUM) && OS(DARWIN)
 #define WTF_PLATFORM_CF 1
 #define WTF_USE_PTHREADS 1
 #define HAVE_PTHREAD_RWLOCK 1
+#define WTF_USE_CARBON_SECURE_INPUT_MODE 1
 #endif
 
 #define DONT_FINALIZE_ON_MAIN_THREAD 1
 #endif
 
 #define DONT_FINALIZE_ON_MAIN_THREAD 1
 #define WTF_PLATFORM_CF 1
 #endif
 
 #define WTF_PLATFORM_CF 1
 #endif
 
+#if OS(DARWIN) && !defined(BUILDING_ON_TIGER) && !PLATFORM(GTK) && !PLATFORM(QT)
+#define ENABLE_PURGEABLE_MEMORY 1
+#endif
+
 #define ENABLE_CONTEXT_MENUS 0
 #define ENABLE_DRAG_SUPPORT 0
 #define ENABLE_FTPDIR 1
 #define ENABLE_GEOLOCATION 1
 #define ENABLE_CONTEXT_MENUS 0
 #define ENABLE_DRAG_SUPPORT 0
 #define ENABLE_FTPDIR 1
 #define ENABLE_GEOLOCATION 1
+#define ENABLE_GEOLOCATION_PERMISSION_CACHE 1
 #define ENABLE_ICONDATABASE 0
 #define ENABLE_ICONDATABASE 0
-#define ENABLE_INSPECTOR 0
-#define ENABLE_JIT 0
-#define ENABLE_MAC_JAVA_BRIDGE 0
+#define ENABLE_JAVA_BRIDGE 0
 #define ENABLE_NETSCAPE_PLUGIN_API 0
 #define ENABLE_ORIENTATION_EVENTS 1
 #define ENABLE_RANGETYPE_AS_TEXT 1
 #define ENABLE_REPAINT_THROTTLING 1
 #define ENABLE_RESPECT_EXIF_ORIENTATION 1
 #define ENABLE_NETSCAPE_PLUGIN_API 0
 #define ENABLE_ORIENTATION_EVENTS 1
 #define ENABLE_RANGETYPE_AS_TEXT 1
 #define ENABLE_REPAINT_THROTTLING 1
 #define ENABLE_RESPECT_EXIF_ORIENTATION 1
-#define ENABLE_YARR 0
-#define ENABLE_YARR_JIT 0
 #define HAVE_PTHREAD_RWLOCK 1
 #define HAVE_READLINE 1
 #define HAVE_RUNLOOP_TIMER 0
 #define HAVE_PTHREAD_RWLOCK 1
 #define HAVE_READLINE 1
 #define HAVE_RUNLOOP_TIMER 0
 #define WTF_USE_PTHREADS 1
 #define WTF_USE_WEB_THREAD 1
 
 #define WTF_USE_PTHREADS 1
 #define WTF_USE_WEB_THREAD 1
 
+#undef ENABLE_PURGEABLE_MEMORY
+
+#if defined(WTF_ARM_ARCH_VERSION) && WTF_ARM_ARCH_VERSION == 6
+#define ENABLE_INSPECTOR 0
+#define ENABLE_PURGEABLE_MEMORY 0
+#else
+#define ENABLE_INSPECTOR 1
+#define ENABLE_PURGEABLE_MEMORY 1
+#endif
+
+#define WTF_USE_PTHREAD_GETSPECIFIC_DIRECT 1
+
+#define ENABLE_JIT 0
+#define ENABLE_YARR 0
+#define ENABLE_YARR_JIT 0
+#ifdef __llvm__
+#define WTF_USE_JSVALUE32_64 1
+#else
+#define WTF_USE_JSVALUE32 1
+#endif
+
+#undef ENABLE_3D_CANVAS
+#if defined(WTF_ARM_ARCH_VERSION) && WTF_ARM_ARCH_VERSION == 6
+#define ENABLE_3D_CANVAS 0
+#else
+#define ENABLE_3D_CANVAS 1
+#endif
+
+
 #if PLATFORM(ANDROID)
 #define WTF_USE_PTHREADS 1
 #define WTF_PLATFORM_SGL 1
 #define USE_SYSTEM_MALLOC 1
 #if PLATFORM(ANDROID)
 #define WTF_USE_PTHREADS 1
 #define WTF_PLATFORM_SGL 1
 #define USE_SYSTEM_MALLOC 1
-#define ENABLE_MAC_JAVA_BRIDGE 1
+#define ENABLE_JAVA_BRIDGE 1
 #define LOG_DISABLED 1
 /* Prevents Webkit from drawing the caret in textfields and textareas
    This prevents unnecessary invals. */
 #define LOG_DISABLED 1
 /* Prevents Webkit from drawing the caret in textfields and textareas
    This prevents unnecessary invals. */
 
 #if PLATFORM(WX)
 #define ENABLE_ASSEMBLER 1
 
 #if PLATFORM(WX)
 #define ENABLE_ASSEMBLER 1
+#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
 #if OS(DARWIN)
 #define WTF_PLATFORM_CF 1
 #if OS(DARWIN)
 #define WTF_PLATFORM_CF 1
+#ifndef BUILDING_ON_TIGER
+#define WTF_USE_CORE_TEXT 1
+#else
+#define WTF_USE_ATSUI 1
+#endif
 #endif
 #endif
 
 #endif
 #endif
 
 #define ENABLE_NETSCAPE_PLUGIN_API 0
 #endif
 
 #define ENABLE_NETSCAPE_PLUGIN_API 0
 #endif
 
+#if PLATFORM(BREWMP)
+#define USE_SYSTEM_MALLOC 1
+#endif
+
 #if !defined(HAVE_ACCESSIBILITY)
 #define HAVE_ACCESSIBILITY 1
 #endif /* !defined(HAVE_ACCESSIBILITY) */
 #if !defined(HAVE_ACCESSIBILITY)
 #define HAVE_ACCESSIBILITY 1
 #endif /* !defined(HAVE_ACCESSIBILITY) */
 
 #if !OS(WINDOWS) && !OS(SOLARIS) && !OS(QNX) \
     && !OS(SYMBIAN) && !OS(HAIKU) && !OS(RVCT) \
 
 #if !OS(WINDOWS) && !OS(SOLARIS) && !OS(QNX) \
     && !OS(SYMBIAN) && !OS(HAIKU) && !OS(RVCT) \
-    && !OS(ANDROID)
+    && !OS(ANDROID) && !PLATFORM(BREWMP)
 #define HAVE_TM_GMTOFF 1
 #define HAVE_TM_ZONE 1
 #define HAVE_TIMEGM 1
 #define HAVE_TM_GMTOFF 1
 #define HAVE_TM_ZONE 1
 #define HAVE_TIMEGM 1
 #define HAVE_SYS_PARAM_H 1
 #endif
 
 #define HAVE_SYS_PARAM_H 1
 #endif
 
+#elif PLATFORM(BREWMP)
+
+#define HAVE_ERRNO_H 1
+
 #elif OS(QNX)
 
 #define HAVE_ERRNO_H 1
 #elif OS(QNX)
 
 #define HAVE_ERRNO_H 1
 
 /* ENABLE macro defaults */
 
 
 /* ENABLE macro defaults */
 
+#if PLATFORM(QT)
+// We musn't customize the global operator new and delete for the Qt port.
+#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
+#endif
+
 /* 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)
 /* 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_DASHBOARD_SUPPORT 0
 #endif
 
 #define ENABLE_DASHBOARD_SUPPORT 0
 #endif
 
+#if !defined(ENABLE_WIDGETS_10_SUPPORT)
+#define ENABLE_WIDGETS_10_SUPPORT 0
+#endif
+
 #if !defined(ENABLE_GEOLOCATION_PERMISSION_CACHE)
 #define ENABLE_GEOLOCATION_PERMISSION_CACHE 0
 #endif
 #if !defined(ENABLE_GEOLOCATION_PERMISSION_CACHE)
 #define ENABLE_GEOLOCATION_PERMISSION_CACHE 0
 #endif
 #define ENABLE_INSPECTOR 1
 #endif
 
 #define ENABLE_INSPECTOR 1
 #endif
 
-#if !defined(ENABLE_MAC_JAVA_BRIDGE)
-#define ENABLE_MAC_JAVA_BRIDGE 0
+#if !defined(ENABLE_JAVA_BRIDGE)
+#define ENABLE_JAVA_BRIDGE 0
 #endif
 
 #if !defined(ENABLE_NETSCAPE_PLUGIN_API)
 #define ENABLE_NETSCAPE_PLUGIN_API 1
 #endif
 
 #endif
 
 #if !defined(ENABLE_NETSCAPE_PLUGIN_API)
 #define ENABLE_NETSCAPE_PLUGIN_API 1
 #endif
 
+#if !defined(ENABLE_PURGEABLE_MEMORY)
+#define ENABLE_PURGEABLE_MEMORY 0
+#endif
+
 #if !defined(WTF_USE_PLUGIN_HOST_PROCESS)
 #define WTF_USE_PLUGIN_HOST_PROCESS 0
 #endif
 #if !defined(WTF_USE_PLUGIN_HOST_PROCESS)
 #define WTF_USE_PLUGIN_HOST_PROCESS 0
 #endif
 #define ENABLE_RESPECT_EXIF_ORIENTATION 0
 #endif
 
 #define ENABLE_RESPECT_EXIF_ORIENTATION 0
 #endif
 
+#if !defined(WTF_USE_PTHREAD_GETSPECIFIC_DIRECT)
+#define WTF_USE_PTHREAD_GETSPECIFIC_DIRECT 0
+#endif
+
 #if !defined(ENABLE_OPCODE_STATS)
 #define ENABLE_OPCODE_STATS 0
 #endif
 
 #if !defined(ENABLE_OPCODE_STATS)
 #define ENABLE_OPCODE_STATS 0
 #endif
 
+#if !defined(ENABLE_GLOBAL_FASTMALLOC_NEW)
+#define ENABLE_GLOBAL_FASTMALLOC_NEW 1
+#endif
+
+#define ENABLE_DEBUG_WITH_BREAKPOINT 0
 #define ENABLE_SAMPLING_COUNTERS 0
 #define ENABLE_SAMPLING_FLAGS 0
 #define ENABLE_OPCODE_SAMPLING 0
 #define ENABLE_SAMPLING_COUNTERS 0
 #define ENABLE_SAMPLING_FLAGS 0
 #define ENABLE_OPCODE_SAMPLING 0
 #define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0
 #endif
 
 #define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0
 #endif
 
+#if !defined(ENABLE_CONTENTEDITABLE)
+#define ENABLE_CONTENTEDITABLE 0
+#endif
+
 #if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64)
 #if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64)
-#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) || CPU(IA64) || CPU(ALPHA)
+#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) \
+    || (CPU(IA64) && !CPU(IA64_32)) \
+    || CPU(ALPHA) \
+    || CPU(SPARC64)
 #define WTF_USE_JSVALUE64 1
 #define WTF_USE_JSVALUE64 1
-#elif CPU(ARM) && !PLATFORM(IPHONE) || CPU(PPC64) || (PLATFORM(IPHONE) && defined(WTF_ARM_ARCH_VERSION) && WTF_ARM_ARCH_VERSION == 6 && !defined(__llvm__))
+#elif CPU(ARM_TRADITIONAL) && !PLATFORM(IPHONE) || CPU(PPC64) || CPU(MIPS) || (PLATFORM(IPHONE) && defined(WTF_ARM_ARCH_VERSION) && WTF_ARM_ARCH_VERSION == 6 && !defined(__llvm__))
 /* FIXME: <rdar://problem/7478149> gcc-4.2 compiler bug with USE(JSVALUE32_64) and armv6 target */
 #define WTF_USE_JSVALUE32 1
 #elif OS(WINDOWS) && COMPILER(MINGW)
 /* FIXME: <rdar://problem/7478149> gcc-4.2 compiler bug with USE(JSVALUE32_64) and armv6 target */
 #define WTF_USE_JSVALUE32 1
 #elif OS(WINDOWS) && COMPILER(MINGW)
@@ -829,12 +948,15 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
     #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
 #elif CPU(ARM_THUMB2) && PLATFORM(IPHONE)
     #define ENABLE_JIT 1
     #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
 #elif CPU(ARM_THUMB2) && PLATFORM(IPHONE)
     #define ENABLE_JIT 1
+/* The JIT is tested & working on Android */
+#elif CPU(ARM_THUMB2) && PLATFORM(ANDROID) && ENABLE(ANDROID_JSC_JIT)
+    #define ENABLE_JIT 1
 /* The JIT is tested & working on x86 Windows */
 #elif CPU(X86) && PLATFORM(WIN)
     #define ENABLE_JIT 1
 #endif
 
 /* The JIT is tested & working on x86 Windows */
 #elif CPU(X86) && PLATFORM(WIN)
     #define ENABLE_JIT 1
 #endif
 
-#if PLATFORM(QT)
+#if PLATFORM(QT) || PLATFORM(WX)
 #if CPU(X86_64) && OS(DARWIN)
     #define ENABLE_JIT 1
 #elif CPU(X86) && OS(DARWIN)
 #if CPU(X86_64) && OS(DARWIN)
     #define ENABLE_JIT 1
 #elif CPU(X86) && OS(DARWIN)
@@ -843,6 +965,8 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #elif CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100
     #define ENABLE_JIT 1
     #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
 #elif CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100
     #define ENABLE_JIT 1
     #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 1
+#elif CPU(X86_64) && OS(WINDOWS) && COMPILER(MINGW64) && GCC_VERSION >= 40100
+    #define ENABLE_JIT 1
 #elif CPU(X86) && OS(WINDOWS) && COMPILER(MSVC)
     #define ENABLE_JIT 1
     #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
 #elif CPU(X86) && OS(WINDOWS) && COMPILER(MSVC)
     #define ENABLE_JIT 1
     #define WTF_USE_JIT_STUB_ARGUMENT_REGISTER 1
@@ -853,17 +977,37 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
     #define ENABLE_JIT 1
 #elif CPU(ARM_TRADITIONAL) && OS(LINUX)
     #define ENABLE_JIT 1
     #define ENABLE_JIT 1
 #elif CPU(ARM_TRADITIONAL) && OS(LINUX)
     #define ENABLE_JIT 1
+#elif CPU(ARM_TRADITIONAL) && OS(SYMBIAN) && COMPILER(RVCT)
+    #define ENABLE_JIT 1
+#elif CPU(MIPS) && OS(LINUX)
+    #define ENABLE_JIT 1
+    #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 0
 #endif
 #endif /* PLATFORM(QT) */
 
 #endif /* !defined(ENABLE_JIT) */
 
 #endif
 #endif /* PLATFORM(QT) */
 
 #endif /* !defined(ENABLE_JIT) */
 
+#if 1 || !ENABLE(JIT)
+#define ENABLE_INTERPRETER 1
+#endif
+
+#if !(ENABLE(JIT) || ENABLE(INTERPRETER))
+#error You have to have at least one execution model enabled to build JSC
+#endif
+
+/* CPU architecture specific optimizations */
+#if CPU(ARM_TRADITIONAL)
+#if ENABLE(JIT) && !defined(ENABLE_JIT_OPTIMIZE_MOD) && WTF_ARM_ARCH_AT_LEAST(5)
+#define ENABLE_JIT_OPTIMIZE_MOD 1
+#endif
+#endif
+
 #if ENABLE(JIT)
 #ifndef ENABLE_JIT_OPTIMIZE_CALL
 #define ENABLE_JIT_OPTIMIZE_CALL 1
 #endif
 #ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL
 #if ENABLE(JIT)
 #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
+#define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 0
 #endif
 #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS
 #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1
 #endif
 #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS
 #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1
@@ -871,6 +1015,9 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS
 #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1
 #endif
 #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS
 #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1
 #endif
+#ifndef ENABLE_JIT_OPTIMIZE_MOD
+#define ENABLE_JIT_OPTIMIZE_MOD 0
+#endif
 #endif
 
 #if CPU(X86) && COMPILER(MSVC)
 #endif
 
 #if CPU(X86) && COMPILER(MSVC)
@@ -881,14 +1028,12 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #define JSC_HOST_CALL
 #endif
 
 #define JSC_HOST_CALL
 #endif
 
-#if COMPILER(GCC) && !ENABLE(JIT)
+#if COMPILER(GCC)
 #define HAVE_COMPUTED_GOTO 1
 #endif
 
 #define HAVE_COMPUTED_GOTO 1
 #endif
 
-#if ENABLE(JIT) && defined(COVERAGE)
-    #define WTF_USE_INTERPRETER 0
-#else
-    #define WTF_USE_INTERPRETER 1
+#if HAVE(COMPUTED_GOTO) && ENABLE(INTERPRETER)
+#define ENABLE_COMPUTED_GOTO_INTERPRETER 1
 #endif
 
 /* Yet Another Regex Runtime. */
 #endif
 
 /* Yet Another Regex Runtime. */
@@ -898,17 +1043,22 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #if (CPU(X86) && PLATFORM(MAC)) \
     || (CPU(X86_64) && PLATFORM(MAC)) \
     || (CPU(ARM_THUMB2) && PLATFORM(IPHONE)) \
 #if (CPU(X86) && PLATFORM(MAC)) \
     || (CPU(X86_64) && PLATFORM(MAC)) \
     || (CPU(ARM_THUMB2) && PLATFORM(IPHONE)) \
-    || (CPU(X86) && PLATFORM(WIN))
+    || (CPU(ARM_THUMB2) && PLATFORM(ANDROID) && ENABLE(ANDROID_JSC_JIT)) \
+    || (CPU(X86) && PLATFORM(WIN)) \
+    || (CPU(X86) && PLATFORM(WX))
 #define ENABLE_YARR 1
 #define ENABLE_YARR_JIT 1
 #endif
 
 #if PLATFORM(QT)
 #if (CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \
 #define ENABLE_YARR 1
 #define ENABLE_YARR_JIT 1
 #endif
 
 #if PLATFORM(QT)
 #if (CPU(X86) && OS(WINDOWS) && COMPILER(MINGW) && GCC_VERSION >= 40100) \
+    || (CPU(X86_64) && OS(WINDOWS) && COMPILER(MINGW64) && GCC_VERSION >= 40100) \
     || (CPU(X86) && OS(WINDOWS) && COMPILER(MSVC)) \
     || (CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100) \
     || (CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100) \
     || (CPU(X86) && OS(WINDOWS) && COMPILER(MSVC)) \
     || (CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100) \
     || (CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100) \
-    || (CPU(ARM_TRADITIONAL) && OS(LINUX))
+    || (CPU(ARM_TRADITIONAL) && OS(LINUX)) \
+    || (CPU(ARM_TRADITIONAL) && OS(SYMBIAN) && COMPILER(RVCT)) \
+    || (CPU(MIPS) && OS(LINUX))
 #define ENABLE_YARR 1
 #define ENABLE_YARR_JIT 1
 #endif
 #define ENABLE_YARR 1
 #define ENABLE_YARR_JIT 1
 #endif
@@ -924,9 +1074,12 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #if ENABLE(JIT) || ENABLE(YARR_JIT)
 #define ENABLE_ASSEMBLER 1
 #endif
 #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. */
-#define ENABLE_ASSEMBLER_WX_EXCLUSIVE 1
+
+/* Pick which allocator to use; we only need an executable allocator if the assembler is compiled in.
+   On x86-64 we use a single fixed mmap, on other platforms we mmap on demand. */
+#if ENABLE(ASSEMBLER)
+#define ENABLE_EXECUTABLE_ALLOCATOR_FIXED 1
+#endif
 
 #if !defined(ENABLE_PAN_SCROLLING) && OS(WINDOWS)
 #define ENABLE_PAN_SCROLLING 1
 
 #if !defined(ENABLE_PAN_SCROLLING) && OS(WINDOWS)
 #define ENABLE_PAN_SCROLLING 1
@@ -943,8 +1096,17 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #define WTF_USE_FONT_FAST_PATH 1
 #endif
 
 #define WTF_USE_FONT_FAST_PATH 1
 #endif
 
-/* Accelerated compositing */
 #if PLATFORM(MAC)
 #if PLATFORM(MAC)
+/* Complex text framework */
+#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
+#define WTF_USE_ATSUI 0
+#define WTF_USE_CORE_TEXT 1
+#else
+#define WTF_USE_ATSUI 1
+#define WTF_USE_CORE_TEXT 0
+#endif
+
+/* Accelerated compositing */
 #if !defined(BUILDING_ON_TIGER)
 #define WTF_USE_ACCELERATED_COMPOSITING 1
 #endif
 #if !defined(BUILDING_ON_TIGER)
 #define WTF_USE_ACCELERATED_COMPOSITING 1
 #endif
@@ -963,6 +1125,10 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
 #endif
 #endif
 
 #endif
 #endif
 
+#if (PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)) || PLATFORM(IPHONE)
+#define WTF_USE_PROTECTION_SPACE_AUTH_CALLBACK 1
+#endif
+
 #if COMPILER(GCC)
 #define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result))
 #else
 #if COMPILER(GCC)
 #define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result))
 #else
diff --git a/wtf/PtrAndFlags.h b/wtf/PtrAndFlags.h
deleted file mode 100644 (file)
index 1e1bee0..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 PtrAndFlags_h
-#define PtrAndFlags_h
-
-#include <wtf/Assertions.h>
-
-namespace WTF {
-    template<class T, typename FlagEnum> class PtrAndFlagsBase {
-    public:
-        bool isFlagSet(FlagEnum flagNumber) const { ASSERT(flagNumber < 2); return m_ptrAndFlags & (1 << flagNumber); }
-        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);
-#ifndef NDEBUG
-            m_leaksPtr = ptr;
-#endif
-        }
-
-        bool operator!() const { return !get(); }
-        T* operator->() const { return reinterpret_cast<T*>(m_ptrAndFlags & ~3); }
-
-    protected:
-        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
-    };
-
-    template<class T, typename FlagEnum> class PtrAndFlags : public PtrAndFlagsBase<T, FlagEnum> {
-    public:
-        PtrAndFlags()
-        {
-            PtrAndFlagsBase<T, FlagEnum>::m_ptrAndFlags = 0;
-        }
-        PtrAndFlags(T* ptr)
-        {
-            PtrAndFlagsBase<T, FlagEnum>::m_ptrAndFlags = 0;
-            PtrAndFlagsBase<T, FlagEnum>::set(ptr);
-        }
-    };
-} // namespace WTF
-
-using WTF::PtrAndFlagsBase;
-using WTF::PtrAndFlags;
-
-#endif // PtrAndFlags_h
index fe1687c6bb985da485c9714c5f871c80ed43f96c..0cd4f71e7fb2bd5ce7893f6a0910ba4e2228fbfb 100644 (file)
@@ -39,4 +39,6 @@ namespace WTF {
 
 }
 
 
 }
 
+using WTF::randomNumber;
+
 #endif
 #endif
index e6d10477c06366725922aa9ece51cc5f435c1d5d..eed793329a472c242bf1c34e6eda83e2b675e43e 100644 (file)
  *
  */
 
  *
  */
 
+// RefPtr and PassRefPtr are documented at http://webkit.org/coding/RefPtr.html
+
 #ifndef WTF_RefPtr_h
 #define WTF_RefPtr_h
 
 #include <algorithm>
 #include "AlwaysInline.h"
 #include "FastAllocBase.h"
 #ifndef WTF_RefPtr_h
 #define WTF_RefPtr_h
 
 #include <algorithm>
 #include "AlwaysInline.h"
 #include "FastAllocBase.h"
+#include "PassRefPtr.h"
 
 namespace WTF {
 
 
 namespace WTF {
 
@@ -37,8 +40,8 @@ namespace WTF {
     template <typename T> class RefPtr : public FastAllocBase {
     public:
         RefPtr() : m_ptr(0) { }
     template <typename T> class RefPtr : public FastAllocBase {
     public:
         RefPtr() : m_ptr(0) { }
-        RefPtr(T* ptr) : m_ptr(ptr) { if (ptr) ptr->ref(); }
-        RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) ptr->ref(); }
+        RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
+        RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { T* ptr = m_ptr; refIfNotNull(ptr); }
         // see comment in PassRefPtr.h for why this takes const reference
         template <typename U> RefPtr(const PassRefPtr<U>&);
         template <typename U> RefPtr(const NonNullPassRefPtr<U>&);
         // see comment in PassRefPtr.h for why this takes const reference
         template <typename U> RefPtr(const PassRefPtr<U>&);
         template <typename U> RefPtr(const NonNullPassRefPtr<U>&);
@@ -50,13 +53,13 @@ namespace WTF {
         RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
         bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
 
         RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { }
         bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); }
 
-        ~RefPtr() { if (T* ptr = m_ptr) ptr->deref(); }
+        ~RefPtr() { derefIfNotNull(m_ptr); }
         
         
-        template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) ptr->ref(); }
+        template <typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { T* ptr = m_ptr; refIfNotNull(ptr); }
         
         T* get() const { return m_ptr; }
         
         
         T* get() const { return m_ptr; }
         
-        void clear() { if (T* ptr = m_ptr) ptr->deref(); m_ptr = 0; }
+        void clear() { derefIfNotNull(m_ptr); m_ptr = 0; }
         PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
 
         T& operator*() const { return *m_ptr; }
         PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; }
 
         T& operator*() const { return *m_ptr; }
@@ -65,12 +68,8 @@ namespace WTF {
         bool operator!() const { return !m_ptr; }
     
         // This conversion operator allows implicit conversion to bool but not to other integer types.
         bool operator!() const { return !m_ptr; }
     
         // This conversion operator allows implicit conversion to bool but not to other integer types.
-#if COMPILER(WINSCW)
-        operator bool() const { return m_ptr; }
-#else
-        typedef T* RefPtr::*UnspecifiedBoolType;
+        typedef T* (RefPtr::*UnspecifiedBoolType);
         operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
         operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; }
-#endif
         
         RefPtr& operator=(const RefPtr&);
         RefPtr& operator=(T*);
         
         RefPtr& operator=(const RefPtr&);
         RefPtr& operator=(T*);
@@ -82,9 +81,9 @@ namespace WTF {
 
         void swap(RefPtr&);
 
 
         void swap(RefPtr&);
 
-    private:
         static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
 
         static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
 
+    private:
         T* m_ptr;
     };
     
         T* m_ptr;
     };
     
@@ -101,35 +100,29 @@ namespace WTF {
     template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
     {
         T* optr = o.get();
     template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o)
     {
         T* optr = o.get();
-        if (optr)
-            optr->ref();
+        refIfNotNull(optr);
         T* ptr = m_ptr;
         m_ptr = optr;
         T* ptr = m_ptr;
         m_ptr = optr;
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
     
     template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
     {
         T* optr = o.get();
         return *this;
     }
     
     template <typename T> template <typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o)
     {
         T* optr = o.get();
-        if (optr)
-            optr->ref();
+        refIfNotNull(optr);
         T* ptr = m_ptr;
         m_ptr = optr;
         T* ptr = m_ptr;
         m_ptr = optr;
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
     
     template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
     {
         return *this;
     }
     
     template <typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr)
     {
-        if (optr)
-            optr->ref();
+        refIfNotNull(optr);
         T* ptr = m_ptr;
         m_ptr = optr;
         T* ptr = m_ptr;
         m_ptr = optr;
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
 
         return *this;
     }
 
@@ -137,8 +130,7 @@ namespace WTF {
     {
         T* ptr = m_ptr;
         m_ptr = o.releaseRef();
     {
         T* ptr = m_ptr;
         m_ptr = o.releaseRef();
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
 
         return *this;
     }
 
@@ -146,8 +138,7 @@ namespace WTF {
     {
         T* ptr = m_ptr;
         m_ptr = o.releaseRef();
     {
         T* ptr = m_ptr;
         m_ptr = o.releaseRef();
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
 
         return *this;
     }
 
@@ -155,8 +146,7 @@ namespace WTF {
     {
         T* ptr = m_ptr;
         m_ptr = o.releaseRef();
     {
         T* ptr = m_ptr;
         m_ptr = o.releaseRef();
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
 
         return *this;
     }
 
@@ -164,8 +154,7 @@ namespace WTF {
     {
         T* ptr = m_ptr;
         m_ptr = o.releaseRef();
     {
         T* ptr = m_ptr;
         m_ptr = o.releaseRef();
-        if (ptr)
-            ptr->deref();
+        derefIfNotNull(ptr);
         return *this;
     }
 
         return *this;
     }
 
diff --git a/wtf/StaticConstructors.h b/wtf/StaticConstructors.h
new file mode 100644 (file)
index 0000000..8b2df9d
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006 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
+ * 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 StaticConstructors_h
+#define StaticConstructors_h
+
+// We need to avoid having static constructors. We achieve this
+// with two separate methods for GCC and MSVC. Both methods prevent the static
+// initializers from being registered and called on program startup. On GCC, we
+// declare the global objects with a different type that can be POD default
+// initialized by the linker/loader. On MSVC we use a special compiler feature
+// to have the CRT ignore our static initializers. The constructors will never
+// be called and the objects will be left uninitialized.
+//
+// With both of these approaches, we must define and explicitly call an init
+// routine that uses placement new to create the objects and overwrite the
+// uninitialized placeholders.
+//
+// This is not completely portable, but is what we have for now without
+// changing how a lot of code accesses these global objects.
+
+#ifdef SKIP_STATIC_CONSTRUCTORS_ON_MSVC
+// - Assume that all includes of this header want ALL of their static
+//   initializers ignored. This is currently the case. This means that if
+//   a .cc includes this header (or it somehow gets included), all static
+//   initializers after the include will not be executed.
+// - We do this with a pragma, so that all of the static initializer pointers
+//   go into our own section, and the CRT won't call them. Eventually it would
+//   be nice if the section was discarded, because we don't want the pointers.
+//   See: http://msdn.microsoft.com/en-us/library/7977wcck(VS.80).aspx
+#pragma warning(disable:4075)
+#pragma init_seg(".unwantedstaticinits")
+#endif
+
+#ifndef SKIP_STATIC_CONSTRUCTORS_ON_GCC
+    // Define an global in the normal way.
+#if COMPILER(MSVC7_OR_LOWER)
+#define DEFINE_GLOBAL(type, name) \
+    const type name;
+#elif COMPILER(WINSCW)
+#define DEFINE_GLOBAL(type, name, arg...) \
+    const type name;
+#else
+#define DEFINE_GLOBAL(type, name, ...) \
+    const type name;
+#endif
+
+#else
+// Define an correctly-sized array of pointers to avoid static initialization.
+// Use an array of pointers instead of an array of char in case there is some alignment issue.
+#if COMPILER(MSVC7_OR_LOWER)
+#define DEFINE_GLOBAL(type, name) \
+    void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
+#elif COMPILER(WINSCW)
+#define DEFINE_GLOBAL(type, name, arg...) \
+    void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
+#else
+#define DEFINE_GLOBAL(type, name, ...) \
+    void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)];
+#endif
+#endif
+
+#endif // StaticConstructors_h
index 9dfb9699725aae558e2e70f76c241546bb1c7e37..96a929c7ed03d065b88b72551334d821605d1009 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef WTF_StdLibExtras_h
 #define WTF_StdLibExtras_h
 
 #ifndef WTF_StdLibExtras_h
 #define WTF_StdLibExtras_h
 
-#include <wtf/Platform.h>
 #include <wtf/Assertions.h>
 
 // Use these to declare and define a static local variable (static T;) so that
 #include <wtf/Assertions.h>
 
 // Use these to declare and define a static local variable (static T;) so that
index b1ec09f095ce570de85cd5f1b40aa6d1b7334fef..28e80b8369f3ea4e772d7095e451e7f093eab5f6 100644 (file)
@@ -46,7 +46,7 @@ inline int snprintf(char* buffer, size_t count, const char* format, ...)
     return result;
 }
 
     return result;
 }
 
-#if COMPILER(MSVC7) || OS(WINCE)
+#if COMPILER(MSVC7_OR_LOWER) || OS(WINCE)
 
 inline int vsnprintf(char* buffer, size_t count, const char* format, va_list args)
 {
 
 inline int vsnprintf(char* buffer, size_t count, const char* format, va_list args)
 {
diff --git a/wtf/ThreadSafeShared.h b/wtf/ThreadSafeShared.h
new file mode 100644 (file)
index 0000000..688747e
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2007, 2008, 2010 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.
+ *
+ *
+ * Note: The implementations of InterlockedIncrement and InterlockedDecrement are based
+ * on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license
+ * is virtually identical to the Apple license above but is included here for completeness.
+ *
+ * Boost Software License - Version 1.0 - August 17th, 2003
+ * 
+ * Permission is hereby granted, free of charge, to any person or organization
+ * obtaining a copy of the software and accompanying documentation covered by
+ * this license (the "Software") to use, reproduce, display, distribute,
+ * execute, and transmit the Software, and to prepare derivative works of the
+ * Software, and to permit third-parties to whom the Software is furnished to
+ * do so, all subject to the following:
+ * 
+ * The copyright notices in the Software and this entire statement, including
+ * the above license grant, this restriction and the following disclaimer,
+ * must be included in all copies of the Software, in whole or in part, and
+ * all derivative works of the Software, unless such copies or derivative
+ * works are solely in the form of machine-executable object code generated by
+ * a source language processor.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+ * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef ThreadSafeShared_h
+#define ThreadSafeShared_h
+
+#include "Platform.h"
+
+#include <wtf/Atomics.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/ThreadingPrimitives.h>
+
+namespace WTF {
+
+class ThreadSafeSharedBase : public Noncopyable {
+public:
+    ThreadSafeSharedBase(int initialRefCount = 1)
+        : m_refCount(initialRefCount)
+    {
+    }
+
+    void ref()
+    {
+#if USE(LOCKFREE_THREADSAFESHARED)
+        atomicIncrement(&m_refCount);
+#else
+        MutexLocker locker(m_mutex);
+        ++m_refCount;
+#endif
+    }
+
+    bool hasOneRef()
+    {
+        return refCount() == 1;
+    }
+
+    int refCount() const
+    {
+#if !USE(LOCKFREE_THREADSAFESHARED)
+        MutexLocker locker(m_mutex);
+#endif
+        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);
+    }
+};
+
+} // namespace WTF
+
+using WTF::ThreadSafeShared;
+
+#endif // ThreadSafeShared_h
index 3abbc5847d72f1f69a4c1e0230a3031e31fc3992..7e5679f9649ffcef42ebaa7e9779c8383f329fc8 100644 (file)
@@ -188,6 +188,11 @@ inline void ThreadSpecific<T>::set(T* ptr)
 
 #elif OS(WINDOWS)
 
 
 #elif OS(WINDOWS)
 
+// TLS_OUT_OF_INDEXES is not defined on WinCE.
+#ifndef TLS_OUT_OF_INDEXES
+#define TLS_OUT_OF_INDEXES 0xffffffff
+#endif
+
 // The maximum number of TLS keys that can be created. For simplification, we assume that:
 // 1) Once the instance of ThreadSpecific<> is created, it will not be destructed until the program dies.
 // 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough.
 // The maximum number of TLS keys that can be created. For simplification, we assume that:
 // 1) Once the instance of ThreadSpecific<> is created, it will not be destructed until the program dies.
 // 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough.
@@ -200,14 +205,14 @@ template<typename T>
 inline ThreadSpecific<T>::ThreadSpecific()
     : m_index(-1)
 {
 inline ThreadSpecific<T>::ThreadSpecific()
     : m_index(-1)
 {
-    DWORD tls_key = TlsAlloc();
-    if (tls_key == TLS_OUT_OF_INDEXES)
+    DWORD tlsKey = TlsAlloc();
+    if (tlsKey == TLS_OUT_OF_INDEXES)
         CRASH();
 
     m_index = InterlockedIncrement(&tlsKeyCount()) - 1;
     if (m_index >= kMaxTlsKeySize)
         CRASH();
         CRASH();
 
     m_index = InterlockedIncrement(&tlsKeyCount()) - 1;
     if (m_index >= kMaxTlsKeySize)
         CRASH();
-    tlsKeys()[m_index] = tls_key;
+    tlsKeys()[m_index] = tlsKey;
 }
 
 template<typename T>
 }
 
 template<typename T>
index 1599562ef5191e64b489cb20cab85652e79b100e..415a8fc83f6d8157ea4c8a396062c03eb444a670 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved.
  * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
  *
  * Redistribution and use in source and binary forms, with or without
  * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
  *
  * Redistribution and use in source and binary forms, with or without
 
 #include "Platform.h"
 
 
 #include "Platform.h"
 
-#if OS(WINCE)
-#include <windows.h>
-#endif
-
+#include <stdint.h>
 #include <wtf/Assertions.h>
 #include <wtf/Assertions.h>
+#include <wtf/Atomics.h>
 #include <wtf/Locker.h>
 #include <wtf/Locker.h>
+#include <wtf/MainThread.h>
 #include <wtf/Noncopyable.h>
 #include <wtf/Noncopyable.h>
-
-#if OS(WINDOWS) && !OS(WINCE)
-#include <windows.h>
-#elif OS(DARWIN)
-#include <libkern/OSAtomic.h>
-#elif OS(ANDROID)
-#include <cutils/atomic.h>
-#elif COMPILER(GCC)
-#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
-#include <ext/atomicity.h>
-#else
-#include <bits/atomicity.h>
-#endif
-#endif
-
-#if USE(PTHREADS)
-#include <pthread.h>
-#elif PLATFORM(GTK)
-#include <wtf/gtk/GOwnPtr.h>
-typedef struct _GMutex GMutex;
-typedef struct _GCond GCond;
-#endif
-
-#if PLATFORM(QT)
-#include <qglobal.h>
-QT_BEGIN_NAMESPACE
-class QMutex;
-class QWaitCondition;
-QT_END_NAMESPACE
-#endif
-
-#include <stdint.h>
+#include <wtf/ThreadSafeShared.h>
+#include <wtf/ThreadingPrimitives.h>
 
 // For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc).
 #define AtomicallyInitializedStatic(T, name) \
 
 // For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc).
 #define AtomicallyInitializedStatic(T, name) \
@@ -112,6 +81,11 @@ namespace WTF {
 typedef uint32_t ThreadIdentifier;
 typedef void* (*ThreadFunction)(void* argument);
 
 typedef uint32_t ThreadIdentifier;
 typedef void* (*ThreadFunction)(void* argument);
 
+// 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();
+
 // 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);
 // 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);
@@ -124,226 +98,18 @@ ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadN
 void initializeCurrentThreadInternal(const char* threadName);
 
 ThreadIdentifier currentThread();
 void initializeCurrentThreadInternal(const char* threadName);
 
 ThreadIdentifier currentThread();
-bool isMainThread();
 int waitForThreadCompletion(ThreadIdentifier, void**);
 void detachThread(ThreadIdentifier);
 
 int waitForThreadCompletion(ThreadIdentifier, void**);
 void detachThread(ThreadIdentifier);
 
-#if USE(PTHREADS)
-typedef pthread_mutex_t PlatformMutex;
-#if HAVE(PTHREAD_RWLOCK)
-typedef pthread_rwlock_t PlatformReadWriteLock;
-#else
-typedef void* PlatformReadWriteLock;
-#endif
-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 OS(WINDOWS)
-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;
-    size_t m_waitersToUnblock; 
-    HANDLE m_blockLock;
-    HANDLE m_blockQueue;
-    HANDLE m_unblockLock;
-
-    bool timedWait(PlatformMutex&, DWORD durationMilliseconds);
-    void signal(bool unblockAll);
-};
-#else
-typedef void* PlatformMutex;
-typedef void* PlatformReadWriteLock;
-typedef void* PlatformCondition;
-#endif
-    
-class Mutex : public Noncopyable {
-public:
-    Mutex();
-    ~Mutex();
-
-    void lock();
-    bool tryLock();
-    void unlock();
-
-public:
-    PlatformMutex& impl() { return m_mutex; }
-private:
-    PlatformMutex m_mutex;
-};
-
-typedef Locker<Mutex> MutexLocker;
-
-class ReadWriteLock : public Noncopyable {
-public:
-    ReadWriteLock();
-    ~ReadWriteLock();
-
-    void readLock();
-    bool tryReadLock();
-
-    void writeLock();
-    bool tryWriteLock();
-    
-    void unlock();
-
-private:
-    PlatformReadWriteLock m_readWriteLock;
-};
-
-class ThreadCondition : public Noncopyable {
-public:
-    ThreadCondition();
-    ~ThreadCondition();
-    
-    void wait(Mutex& mutex);
-    // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past.
-    // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime().
-    bool timedWait(Mutex&, double absoluteTime);
-    void signal();
-    void broadcast();
-    
-private:
-    PlatformCondition m_condition;
-};
-
-#if OS(WINDOWS)
-#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
-
-#if COMPILER(MINGW) || COMPILER(MSVC7) || OS(WINCE)
-inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); }
-inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); }
-#else
-inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); }
-inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); }
-#endif
-
-#elif OS(DARWIN)
-#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
-
-inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); }
-inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); }
-
-#elif OS(ANDROID)
-
-inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); }
-inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); }
-
-#elif COMPILER(GCC) && !CPU(SPARC64) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc
-#define WTF_USE_LOCKFREE_THREADSAFESHARED 1
-
-inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; }
-inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; }
-
-#endif
-
-class ThreadSafeSharedBase : public Noncopyable {
-public:
-    ThreadSafeSharedBase(int initialRefCount = 1)
-        : m_refCount(initialRefCount)
-    {
-    }
-
-    void ref()
-    {
-#if USE(LOCKFREE_THREADSAFESHARED)
-        atomicIncrement(&m_refCount);
-#else
-        MutexLocker locker(m_mutex);
-        ++m_refCount;
-#endif
-    }
-
-    bool hasOneRef()
-    {
-        return refCount() == 1;
-    }
-
-    int refCount() const
-    {
-#if !USE(LOCKFREE_THREADSAFESHARED)
-        MutexLocker locker(m_mutex);
-#endif
-        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();
 
 void lockAtomicallyInitializedStaticMutex();
 void unlockAtomicallyInitializedStaticMutex();
 
 } // namespace WTF
 
 
 void lockAtomicallyInitializedStaticMutex();
 void unlockAtomicallyInitializedStaticMutex();
 
 } // namespace WTF
 
-using WTF::Mutex;
-using WTF::MutexLocker;
-using WTF::ThreadCondition;
 using WTF::ThreadIdentifier;
 using WTF::ThreadIdentifier;
-using WTF::ThreadSafeShared;
-
-#if USE(LOCKFREE_THREADSAFESHARED)
-using WTF::atomicDecrement;
-using WTF::atomicIncrement;
-#endif
-
 using WTF::createThread;
 using WTF::currentThread;
 using WTF::createThread;
 using WTF::currentThread;
-using WTF::isMainThread;
 using WTF::detachThread;
 using WTF::waitForThreadCompletion;
 
 using WTF::detachThread;
 using WTF::waitForThreadCompletion;
 
diff --git a/wtf/ThreadingPrimitives.h b/wtf/ThreadingPrimitives.h
new file mode 100644 (file)
index 0000000..66801c0
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2007, 2008, 2010 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.
+ *
+ */
+
+#ifndef ThreadingPrimitives_h
+#define ThreadingPrimitives_h
+
+#include "Platform.h"
+
+#include <wtf/Assertions.h>
+#include <wtf/Locker.h>
+#include <wtf/Noncopyable.h>
+
+#if OS(WINDOWS)
+#include <windows.h>
+#endif
+
+#if USE(PTHREADS)
+#include <pthread.h>
+#elif PLATFORM(GTK)
+#include "GOwnPtr.h"
+typedef struct _GMutex GMutex;
+typedef struct _GCond GCond;
+#endif
+
+#if PLATFORM(QT)
+#include <qglobal.h>
+QT_BEGIN_NAMESPACE
+class QMutex;
+class QWaitCondition;
+QT_END_NAMESPACE
+#endif
+
+namespace WTF {
+
+#if USE(PTHREADS)
+typedef pthread_mutex_t PlatformMutex;
+#if HAVE(PTHREAD_RWLOCK)
+typedef pthread_rwlock_t PlatformReadWriteLock;
+#else
+typedef void* PlatformReadWriteLock;
+#endif
+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 OS(WINDOWS)
+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;
+    size_t m_waitersToUnblock; 
+    HANDLE m_blockLock;
+    HANDLE m_blockQueue;
+    HANDLE m_unblockLock;
+
+    bool timedWait(PlatformMutex&, DWORD durationMilliseconds);
+    void signal(bool unblockAll);
+};
+#else
+typedef void* PlatformMutex;
+typedef void* PlatformReadWriteLock;
+typedef void* PlatformCondition;
+#endif
+    
+class Mutex : public Noncopyable {
+public:
+    Mutex();
+    ~Mutex();
+
+    void lock();
+    bool tryLock();
+    void unlock();
+
+public:
+    PlatformMutex& impl() { return m_mutex; }
+private:
+    PlatformMutex m_mutex;
+};
+
+typedef Locker<Mutex> MutexLocker;
+
+class ReadWriteLock : public Noncopyable {
+public:
+    ReadWriteLock();
+    ~ReadWriteLock();
+
+    void readLock();
+    bool tryReadLock();
+
+    void writeLock();
+    bool tryWriteLock();
+    
+    void unlock();
+
+private:
+    PlatformReadWriteLock m_readWriteLock;
+};
+
+class ThreadCondition : public Noncopyable {
+public:
+    ThreadCondition();
+    ~ThreadCondition();
+    
+    void wait(Mutex& mutex);
+    // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past.
+    // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime().
+    bool timedWait(Mutex&, double absoluteTime);
+    void signal();
+    void broadcast();
+    
+private:
+    PlatformCondition m_condition;
+};
+
+} // namespace WTF
+
+using WTF::Mutex;
+using WTF::MutexLocker;
+using WTF::ThreadCondition;
+
+#endif // ThreadingPrimitives_h
index 2feb80829544f4d7ce59cbe8a5ff86e4dfba109d..f468ce2d72350e6f13483e48f6a7e73105c423e4 100644 (file)
@@ -57,10 +57,6 @@ typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap;
 
 static Mutex* atomicallyInitializedStaticMutex;
 
 
 static Mutex* atomicallyInitializedStaticMutex;
 
-#if !OS(DARWIN) || PLATFORM(CHROMIUM) || USE(WEB_THREAD)
-static pthread_t mainThread; // The thread that was the first to call initializeThreading(), which must be the main thread.
-#endif
-
 void clearPthreadHandleForIdentifier(ThreadIdentifier);
 
 static Mutex& threadMapMutex()
 void clearPthreadHandleForIdentifier(ThreadIdentifier);
 
 static Mutex& threadMapMutex()
@@ -71,15 +67,12 @@ static Mutex& threadMapMutex()
 
 void initializeThreading()
 {
 
 void initializeThreading()
 {
-    if (!atomicallyInitializedStaticMutex) {
-        atomicallyInitializedStaticMutex = new Mutex;
-        threadMapMutex();
-        initializeRandomNumberGenerator();
-#if !OS(DARWIN) || PLATFORM(CHROMIUM) || USE(WEB_THREAD)
-        mainThread = pthread_self();
-#endif
-        initializeMainThread();
-    }
+    if (atomicallyInitializedStaticMutex)
+        return;
+
+    atomicallyInitializedStaticMutex = new Mutex;
+    threadMapMutex();
+    initializeRandomNumberGenerator();
 }
 
 void lockAtomicallyInitializedStaticMutex()
 }
 
 void lockAtomicallyInitializedStaticMutex()
@@ -240,15 +233,6 @@ ThreadIdentifier currentThread()
     return id;
 }
 
     return id;
 }
 
-bool isMainThread()
-{
-#if OS(DARWIN) && !PLATFORM(CHROMIUM) && !USE(WEB_THREAD)
-    return pthread_main_np();
-#else
-    return pthread_equal(pthread_self(), mainThread);
-#endif
-}
-
 Mutex::Mutex()
 {
     pthread_mutex_init(&m_mutex, NULL);
 Mutex::Mutex()
 {
     pthread_mutex_init(&m_mutex, NULL);
index 73c3f0c14d1cef386caf344f261eb5f8354abb00..c16be5aa86de3c8b1ad7de92bbfe19568bd7a8ee 100644 (file)
@@ -145,8 +145,6 @@ void unlockAtomicallyInitializedStaticMutex()
     atomicallyInitializedStaticMutex->unlock();
 }
 
     atomicallyInitializedStaticMutex->unlock();
 }
 
-static ThreadIdentifier mainThreadIdentifier;
-
 static Mutex& threadMapMutex()
 {
     static Mutex mutex;
 static Mutex& threadMapMutex()
 {
     static Mutex mutex;
@@ -155,14 +153,12 @@ static Mutex& threadMapMutex()
 
 void initializeThreading()
 {
 
 void initializeThreading()
 {
-    if (!atomicallyInitializedStaticMutex) {
-        atomicallyInitializedStaticMutex = new Mutex;
-        threadMapMutex();
-        initializeRandomNumberGenerator();
-        initializeMainThread();
-        mainThreadIdentifier = currentThread();
-        initializeCurrentThreadInternal("Main Thread");
-    }
+    if (atomicallyInitializedStaticMutex)
+        return;
+
+    atomicallyInitializedStaticMutex = new Mutex;
+    threadMapMutex();
+    initializeRandomNumberGenerator();
 }
 
 static HashMap<DWORD, HANDLE>& threadMap()
 }
 
 static HashMap<DWORD, HANDLE>& threadMap()
@@ -275,11 +271,6 @@ ThreadIdentifier currentThread()
     return static_cast<ThreadIdentifier>(GetCurrentThreadId());
 }
 
     return static_cast<ThreadIdentifier>(GetCurrentThreadId());
 }
 
-bool isMainThread()
-{
-    return currentThread() == mainThreadIdentifier;
-}
-
 Mutex::Mutex()
 {
     m_mutex.m_recursionCount = 0;
 Mutex::Mutex()
 {
     m_mutex.m_recursionCount = 0;
index 34e24942fc60efe3a93527a928c9a8a0cb49eb53..6600050a1827996453e2379662df117810ecf6c0 100644 (file)
 #ifndef VMTags_h
 #define VMTags_h
 
 #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. 
 // 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 OS(DARWIN) && !defined(BUILDING_ON_TIGER)
+#if OS(DARWIN)
 
 #include <mach/vm_statistics.h>
 
 
 #include <mach/vm_statistics.h>
 
+#if !defined(TARGETING_TIGER)
+
 #if defined(VM_MEMORY_TCMALLOC)
 #define VM_TAG_FOR_TCMALLOC_MEMORY VM_MAKE_TAG(VM_MEMORY_TCMALLOC)
 #else
 #define VM_TAG_FOR_TCMALLOC_MEMORY VM_MAKE_TAG(53)
 #endif // defined(VM_MEMORY_TCMALLOC)
 
 #if defined(VM_MEMORY_TCMALLOC)
 #define VM_TAG_FOR_TCMALLOC_MEMORY VM_MAKE_TAG(VM_MEMORY_TCMALLOC)
 #else
 #define VM_TAG_FOR_TCMALLOC_MEMORY VM_MAKE_TAG(53)
 #endif // defined(VM_MEMORY_TCMALLOC)
 
-#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)
+#if defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
 #define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
 #else
 #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_EXECUTABLEALLOCATOR_MEMORY VM_MAKE_TAG(64)
+#endif // defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
+
+#if defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
+#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
+#else
 #define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(65)
 #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)
+#endif // defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
+
+#else // !defined(TARGETING_TIGER)
+
+// mmap on Tiger fails with tags that work on Leopard, so fall
+// back to Tiger-compatible tags (that also work on Leopard)
+// when targeting Tiger.
+#define VM_TAG_FOR_TCMALLOC_MEMORY -1
+#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1
+#define VM_TAG_FOR_REGISTERFILE_MEMORY -1
+
+#endif // !defined(TARGETING_TIGER)
+
+// Tags for vm_map and vm_allocate work on both Tiger and Leopard.
+
+#if defined(VM_MEMORY_JAVASCRIPT_CORE)
+#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_CORE)
+#else
+#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(63)
+#endif // defined(VM_MEMORY_JAVASCRIPT_CORE)
 
 #if defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
 #define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
 
 #if defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
 #define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
@@ -56,7 +77,7 @@
 #define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(69)
 #endif // defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
 
 #define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(69)
 #endif // defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
 
-#else // OS(DARWIN) && !defined(BUILDING_ON_TIGER)
+#else // OS(DARWIN)
 
 #define VM_TAG_FOR_TCMALLOC_MEMORY -1
 #define VM_TAG_FOR_COLLECTOR_MEMORY -1
 
 #define VM_TAG_FOR_TCMALLOC_MEMORY -1
 #define VM_TAG_FOR_COLLECTOR_MEMORY -1
@@ -64,6 +85,6 @@
 #define VM_TAG_FOR_REGISTERFILE_MEMORY -1
 #define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY -1
 
 #define VM_TAG_FOR_REGISTERFILE_MEMORY -1
 #define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY -1
 
-#endif // OS(DARWIN) && !defined(BUILDING_ON_TIGER)
+#endif // OS(DARWIN)
 
 #endif // VMTags_h
 
 #endif // VMTags_h
index cd321b857d4d87a0cee51cd0e47c8815d6af21b0..2a86eb0f23c8e14808142681912601c75dc3af28 100644 (file)
 #ifndef ValueCheck_h
 #define ValueCheck_h
 
 #ifndef ValueCheck_h
 #define ValueCheck_h
 
-// For malloc_size and _msize.
-#if OS(DARWIN)
-#include <malloc/malloc.h>
-#elif COMPILER(MSVC)
-#include <malloc.h>
-#endif
+#include <wtf/FastMalloc.h>
 
 namespace WTF {
 
 
 namespace WTF {
 
@@ -47,13 +42,7 @@ template<typename P> struct ValueCheck<P*> {
     {
         if (!p)
             return;
     {
         if (!p)
             return;
-#if (defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) || !defined(NDEBUG)
-#if OS(DARWIN)
-        ASSERT(malloc_size(p));
-#elif COMPILER(MSVC)
-        ASSERT(_msize(const_cast<P*>(p)));
-#endif
-#endif
+        ASSERT(fastMallocSize(p));
         ValueCheck<P>::checkConsistency(*p);
     }
 };
         ValueCheck<P>::checkConsistency(*p);
     }
 };
index 5054449e4fbd7f276f415b03359b7211371d2466..dafa12ade997316a3c9c7cb931847b13d39fe26d 100644 (file)
@@ -286,6 +286,20 @@ namespace WTF {
             m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T)));
         }
 
             m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T)));
         }
 
+        bool tryAllocateBuffer(size_t newCapacity)
+        {
+            if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T))
+                return false;
+
+            T* newBuffer;
+            if (tryFastMalloc(newCapacity * sizeof(T)).getValue(newBuffer)) {
+                m_capacity = newCapacity;
+                m_buffer = newBuffer;
+                return true;
+            }
+            return false;
+        }
+
         void deallocateBuffer(T* bufferToDeallocate)
         {
             if (m_buffer == bufferToDeallocate) {
         void deallocateBuffer(T* bufferToDeallocate)
         {
             if (m_buffer == bufferToDeallocate) {
@@ -361,6 +375,7 @@ namespace WTF {
         void restoreInlineBufferIfNeeded() { }
 
         using Base::allocateBuffer;
         void restoreInlineBufferIfNeeded() { }
 
         using Base::allocateBuffer;
+        using Base::tryAllocateBuffer;
         using Base::deallocateBuffer;
 
         using Base::buffer;
         using Base::deallocateBuffer;
 
         using Base::buffer;
@@ -405,6 +420,15 @@ namespace WTF {
             }
         }
 
             }
         }
 
+        bool tryAllocateBuffer(size_t newCapacity)
+        {
+            if (newCapacity > inlineCapacity)
+                return Base::tryAllocateBuffer(newCapacity);
+            m_buffer = inlineBuffer();
+            m_capacity = inlineCapacity;
+            return true;
+        }
+
         void deallocateBuffer(T* bufferToDeallocate)
         {
             if (bufferToDeallocate == inlineBuffer())
         void deallocateBuffer(T* bufferToDeallocate)
         {
             if (bufferToDeallocate == inlineBuffer())
@@ -543,6 +567,7 @@ namespace WTF {
         void grow(size_t size);
         void resize(size_t size);
         void reserveCapacity(size_t newCapacity);
         void grow(size_t size);
         void resize(size_t size);
         void reserveCapacity(size_t newCapacity);
+        bool tryReserveCapacity(size_t newCapacity);
         void reserveInitialCapacity(size_t initialCapacity);
         void shrinkCapacity(size_t newCapacity);
         void shrinkToFit() { shrinkCapacity(size()); }
         void reserveInitialCapacity(size_t initialCapacity);
         void shrinkCapacity(size_t newCapacity);
         void shrinkToFit() { shrinkCapacity(size()); }
@@ -553,6 +578,7 @@ namespace WTF {
         template<typename U> void append(const U&);
         template<typename U> void uncheckedAppend(const U& val);
         template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&);
         template<typename U> void append(const U&);
         template<typename U> void uncheckedAppend(const U& val);
         template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&);
+        template<typename U> bool tryAppend(const U*, size_t);
 
         template<typename U> void insert(size_t position, const U*, size_t);
         template<typename U> void insert(size_t position, const U&);
 
         template<typename U> void insert(size_t position, const U*, size_t);
         template<typename U> void insert(size_t position, const U&);
@@ -597,6 +623,8 @@ namespace WTF {
     private:
         void expandCapacity(size_t newMinCapacity);
         const T* expandCapacity(size_t newMinCapacity, const T*);
     private:
         void expandCapacity(size_t newMinCapacity);
         const T* expandCapacity(size_t newMinCapacity, const T*);
+        bool tryExpandCapacity(size_t newMinCapacity);
+        const T* tryExpandCapacity(size_t newMinCapacity, const T*);
         template<typename U> U* expandCapacity(size_t newMinCapacity, U*); 
 
         size_t m_size;
         template<typename U> U* expandCapacity(size_t newMinCapacity, U*); 
 
         size_t m_size;
@@ -747,6 +775,26 @@ namespace WTF {
         return begin() + index;
     }
 
         return begin() + index;
     }
 
+    template<typename T, size_t inlineCapacity>
+    bool Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity)
+    {
+        return tryReserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));
+    }
+    
+    template<typename T, size_t inlineCapacity>
+    const T* Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity, const T* ptr)
+    {
+        if (ptr < begin() || ptr >= end()) {
+            if (!tryExpandCapacity(newMinCapacity))
+                return 0;
+            return ptr;
+        }
+        size_t index = ptr - begin();
+        if (!tryExpandCapacity(newMinCapacity))
+            return 0;
+        return begin() + index;
+    }
+
     template<typename T, size_t inlineCapacity> template<typename U>
     inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
     {
     template<typename T, size_t inlineCapacity> template<typename U>
     inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr)
     {
@@ -801,6 +849,21 @@ namespace WTF {
         m_buffer.deallocateBuffer(oldBuffer);
     }
     
         m_buffer.deallocateBuffer(oldBuffer);
     }
     
+    template<typename T, size_t inlineCapacity>
+    bool Vector<T, inlineCapacity>::tryReserveCapacity(size_t newCapacity)
+    {
+        if (newCapacity <= capacity())
+            return true;
+        T* oldBuffer = begin();
+        T* oldEnd = end();
+        if (!m_buffer.tryAllocateBuffer(newCapacity))
+            return false;
+        ASSERT(begin());
+        TypeOperations::move(oldBuffer, oldEnd, begin());
+        m_buffer.deallocateBuffer(oldBuffer);
+        return true;
+    }
+    
     template<typename T, size_t inlineCapacity>
     inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity)
     {
     template<typename T, size_t inlineCapacity>
     inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity)
     {
@@ -852,6 +915,25 @@ namespace WTF {
         m_size = newSize;
     }
 
         m_size = newSize;
     }
 
+    template<typename T, size_t inlineCapacity> template<typename U>
+    bool Vector<T, inlineCapacity>::tryAppend(const U* data, size_t dataSize)
+    {
+        size_t newSize = m_size + dataSize;
+        if (newSize > capacity()) {
+            data = tryExpandCapacity(newSize, data);
+            if (!data)
+                return false;
+            ASSERT(begin());
+        }
+        if (newSize < m_size)
+            return false;
+        T* dest = end();
+        for (size_t i = 0; i < dataSize; ++i)
+            new (&dest[i]) T(data[i]);
+        m_size = newSize;
+        return true;
+    }
+
     template<typename T, size_t inlineCapacity> template<typename U>
     ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val)
     {
     template<typename T, size_t inlineCapacity> template<typename U>
     ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val)
     {
@@ -862,7 +944,7 @@ namespace WTF {
                 return;
         }
             
                 return;
         }
             
-#if COMPILER(MSVC7)
+#if COMPILER(MSVC7_OR_LOWER)
         // FIXME: MSVC7 generates compilation errors when trying to assign
         // a pointer to a Vector of its base class (i.e. can't downcast). So far
         // I've been unable to determine any logical reason for this, so I can
         // FIXME: MSVC7 generates compilation errors when trying to assign
         // a pointer to a Vector of its base class (i.e. can't downcast). So far
         // I've been unable to determine any logical reason for this, so I can
diff --git a/wtf/Vector3.h b/wtf/Vector3.h
new file mode 100644 (file)
index 0000000..3c40b61
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2010 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:
+ *
+ * 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 Vector3_h
+#define Vector3_h
+
+#include <math.h>
+
+namespace WebCore {
+
+class Vector3 {
+public:
+    Vector3()
+        : m_x(0.0)
+        , m_y(0.0)
+        , m_z(0.0)
+    {
+    }
+
+    Vector3(double x, double y, double z)
+        : m_x(x)
+        , m_y(y)
+        , m_z(z)
+    {
+    }
+
+    Vector3(const float p[3])
+        : m_x(p[0])
+        , m_y(p[1])
+        , m_z(p[2])
+    {
+    }
+
+    Vector3(const double p[3])
+        : m_x(p[0])
+        , m_y(p[1])
+        , m_z(p[2])
+    {
+    }
+
+    double abs() const
+    {
+        return sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
+    }
+
+    bool isZero() const
+    {
+        return !m_x && !m_y && !m_z;
+    }
+
+    void normalize()
+    {
+        double absValue = abs();
+        if (!absValue)
+            return;
+
+        double k = 1.0 / absValue;
+        m_x *= k;
+        m_y *= k;
+        m_z *= k;
+    }
+
+    double x() const { return m_x; }
+    double y() const { return m_y; }
+    double z() const { return m_z; }
+
+private:
+    double m_x;
+    double m_y;
+    double m_z;
+};
+
+inline Vector3 operator+(const Vector3& v1, const Vector3& v2)
+{
+    return Vector3(v1.x() + v2.x(), v1.y() + v2.y(), v1.z() + v2.z());
+}
+
+inline Vector3 operator-(const Vector3& v1, const Vector3& v2)
+{
+    return Vector3(v1.x() - v2.x(), v1.y() - v2.y(), v1.z() - v2.z());
+}
+
+inline Vector3 operator*(double k, const Vector3& v)
+{
+    return Vector3(k * v.x(), k * v.y(), k * v.z());
+}
+
+inline Vector3 operator*(const Vector3& v, double k)
+{
+    return Vector3(k * v.x(), k * v.y(), k * v.z());
+}
+
+inline double dot(const Vector3& v1, const Vector3& v2)
+{
+    return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
+}
+
+inline Vector3 cross(const Vector3& v1, const Vector3& v2)
+{
+    double x3 = v1.y() * v2.z() - v1.z() * v2.y();
+    double y3 = v1.z() * v2.x() - v1.x() * v2.z();
+    double z3 = v1.x() * v2.y() - v1.y() * v2.x();
+    return Vector3(x3, y3, z3);
+}
+
+inline double distance(const Vector3& v1, const Vector3& v2)
+{
+    return (v1 - v2).abs();
+}
+
+} // WebCore
+
+#endif // Vector3_h
index bf7787834d2a6c1e3c97abf41dfcec5fc5af59ac..3f33b290d97c6055265241c3d524069562c04dd7 100644 (file)
@@ -80,9 +80,6 @@ namespace WTF {
     template<typename P>
     struct VectorTraits<OwnPtr<P> > : SimpleClassVectorTraits { };
 
     template<typename P>
     struct VectorTraits<OwnPtr<P> > : SimpleClassVectorTraits { };
 
-    template<typename P>
-    struct VectorTraits<std::auto_ptr<P> > : SimpleClassVectorTraits { };
-
     template<typename First, typename Second>
     struct VectorTraits<pair<First, Second> >
     {
     template<typename First, typename Second>
     struct VectorTraits<pair<First, Second> >
     {
diff --git a/wtf/WTFThreadData.cpp b/wtf/WTFThreadData.cpp
new file mode 100644 (file)
index 0000000..70fbda6
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2008, 2010 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 COMPUTER, 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 COMPUTER, 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 "WTFThreadData.h"
+
+namespace WTF {
+
+#if WTFTHREADDATA_MULTITHREADED
+ThreadSpecific<WTFThreadData>* WTFThreadData::staticData;
+#else
+WTFThreadData* WTFThreadData::staticData;
+#endif
+
+WTFThreadData::WTFThreadData()
+    : m_atomicStringTable(0)
+    , m_atomicStringTableDestructor(0)
+{
+    static JSC::IdentifierTable* sharedIdentifierTable = new JSC::IdentifierTable();
+    if (pthread_main_np() || isWebThread())
+        m_defaultIdentifierTable = sharedIdentifierTable;
+    else
+        m_defaultIdentifierTable = new JSC::IdentifierTable();
+
+    m_currentIdentifierTable = m_defaultIdentifierTable;
+}
+
+WTFThreadData::~WTFThreadData()
+{
+    if (m_atomicStringTableDestructor)
+        m_atomicStringTableDestructor(m_atomicStringTable);
+    delete m_defaultIdentifierTable;
+}
+
+} // namespace WebCore
diff --git a/wtf/WTFThreadData.h b/wtf/WTFThreadData.h
new file mode 100644 (file)
index 0000000..510a0e0
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * 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 COMPUTER, 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 COMPUTER, 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 WTFThreadData_h
+#define WTFThreadData_h
+
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/text/StringHash.h>
+
+// This was ENABLE(WORKERS) in WebCore, but this is not defined when compiling JSC.
+// However this check was not correct anyway, re this comment:
+//    // FIXME: Workers are not necessarily the only feature that make per-thread global data necessary.
+//    // We need to check for e.g. database objects manipulating strings on secondary threads.
+// Always enabling this is safe, and should be a better option until we can come up
+// with a better define.
+#define WTFTHREADDATA_MULTITHREADED 1
+
+#if WTFTHREADDATA_MULTITHREADED
+#include <wtf/ThreadSpecific.h>
+#include <wtf/Threading.h>
+#endif
+
+// FIXME: This is a temporary layering violation while we move more string code to WTF.
+namespace WebCore {
+class AtomicStringTable;
+class StringImpl;
+}
+using WebCore::StringImpl;
+
+typedef void (*AtomicStringTableDestructor)(WebCore::AtomicStringTable*);
+
+#if USE(JSC)
+// FIXME: This is a temporary layering violation while we move more string code to WTF.
+namespace JSC {
+
+typedef HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > LiteralIdentifierTable;
+
+class IdentifierTable : public FastAllocBase {
+public:
+    ~IdentifierTable();
+
+    std::pair<HashSet<StringImpl*>::iterator, bool> add(StringImpl* value);
+    template<typename U, typename V>
+    std::pair<HashSet<StringImpl*>::iterator, bool> add(U value);
+
+    void remove(StringImpl* r) { m_table.remove(r); }
+
+    LiteralIdentifierTable& literalTable() { return m_literalTable; }
+
+private:
+    HashSet<StringImpl*> m_table;
+    LiteralIdentifierTable m_literalTable;
+};
+
+}
+#endif
+
+namespace WTF {
+
+class WTFThreadData : public Noncopyable {
+public:
+    WTFThreadData();
+    ~WTFThreadData();
+
+    WebCore::AtomicStringTable* atomicStringTable()
+    {
+        return m_atomicStringTable;
+    }
+
+#if USE(JSC)
+
+    JSC::IdentifierTable* currentIdentifierTable()
+    {
+        return m_currentIdentifierTable;
+    }
+
+    JSC::IdentifierTable* setCurrentIdentifierTable(JSC::IdentifierTable* identifierTable)
+    {
+        JSC::IdentifierTable* oldIdentifierTable = m_currentIdentifierTable;
+        m_currentIdentifierTable = identifierTable;
+        return oldIdentifierTable;
+    }
+
+    void resetCurrentIdentifierTable()
+    {
+        m_currentIdentifierTable = m_defaultIdentifierTable;
+    }
+#endif
+
+private:
+    WebCore::AtomicStringTable* m_atomicStringTable;
+    AtomicStringTableDestructor m_atomicStringTableDestructor;
+
+#if USE(JSC)
+    JSC::IdentifierTable* m_defaultIdentifierTable;
+    JSC::IdentifierTable* m_currentIdentifierTable;
+#endif
+
+#if WTFTHREADDATA_MULTITHREADED
+    static JS_EXPORTDATA ThreadSpecific<WTFThreadData>* staticData;
+#else
+    static JS_EXPORTDATA WTFThreadData* staticData;
+#endif
+    friend WTFThreadData& wtfThreadData();
+    friend class WebCore::AtomicStringTable;
+};
+
+inline WTFThreadData& wtfThreadData()
+{
+#if WTFTHREADDATA_MULTITHREADED
+    // WRT WebCore:
+    //    WTFThreadData is used on main thread before it could possibly be used
+    //    on secondary ones, so there is no need for synchronization here.
+    // WRT JavaScriptCore:
+    //    wtfThreadData() is initially called from initializeThreading(), ensuring
+    //    this is initially called in a pthread_once locked context.
+    if (!WTFThreadData::staticData)
+        WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>;
+    return **WTFThreadData::staticData;
+#else
+    if (!WTFThreadData::staticData) {
+        WTFThreadData::staticData = static_cast<WTFThreadData*>(fastMalloc(sizeof(WTFThreadData)));
+        // WTFThreadData constructor indirectly uses staticData, so we need to set up the memory before invoking it.
+        new (WTFThreadData::staticData) WTFThreadData;
+    }
+    return *WTFThreadData::staticData;
+#endif
+}
+
+} // namespace WTF
+
+using WTF::WTFThreadData;
+using WTF::wtfThreadData;
+
+#endif // WTFThreadData_h
diff --git a/wtf/brew/MainThreadBrew.cpp b/wtf/brew/MainThreadBrew.cpp
new file mode 100644 (file)
index 0000000..2690ea5
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 Company 100, 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. 
+ * 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 "MainThread.h"
+
+namespace WTF {
+
+void initializeMainThreadPlatform()
+{
+    // not implemented
+}
+
+void scheduleDispatchFunctionsOnMainThread()
+{
+    // not implemented
+}
+
+} // namespace WTF
+
diff --git a/wtf/brew/OwnPtrBrew.cpp b/wtf/brew/OwnPtrBrew.cpp
new file mode 100644 (file)
index 0000000..c8384e1
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 Company 100 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 COMPUTER, 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 COMPUTER, 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 "OwnPtr.h"
+
+#include <AEEBitmap.h>
+#include <AEEFile.h>
+#include <AEEStdLib.h>
+
+namespace WTF {
+
+void deleteOwnedPtr(IFileMgr* ptr)
+{
+    if (ptr)
+        IFILEMGR_Release(ptr);
+}
+
+void deleteOwnedPtr(IFile* ptr)
+{
+    if (ptr)
+        IFILE_Release(ptr);
+}
+
+void deleteOwnedPtr(IBitmap* ptr)
+{
+    if (ptr)
+        IBitmap_Release(ptr);
+}
+
+}
diff --git a/wtf/brew/ShellBrew.h b/wtf/brew/ShellBrew.h
new file mode 100644 (file)
index 0000000..7416eca
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2010 Company 100 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 ShellBrew_h
+#define ShellBrew_h
+
+#include <AEEAppGen.h>
+#include <AEEStdLib.h>
+
+#include <wtf/Assertions.h>
+#include <wtf/PassOwnPtr.h>
+
+namespace WTF {
+
+template <typename T>
+static inline PassOwnPtr<T> createInstance(AEECLSID cls)
+{
+    T* instance = 0;
+
+    IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell;
+    ISHELL_CreateInstance(shell, cls, reinterpret_cast<void**>(&instance));
+    ASSERT(instance);
+
+    return instance;
+}
+
+} // namespace WTF
+
+using WTF::createInstance;
+
+#endif // ShellBrew_h
diff --git a/wtf/brew/SystemMallocBrew.h b/wtf/brew/SystemMallocBrew.h
new file mode 100644 (file)
index 0000000..c973b30
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2010 Company 100, 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. 
+ * 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 SystemMallocBrew_h
+#define SystemMallocBrew_h
+
+#include <AEEStdLib.h>
+
+static inline void* mallocBrew(size_t n)
+{
+    // By default, memory allocated using MALLOC() is initialized
+    // to zero. This behavior can be disabled by performing a bitwise
+    // OR of the flag ALLOC_NO_ZMEM with the dwSize parameter.
+    return MALLOC(n | ALLOC_NO_ZMEM);
+}
+
+static inline void* callocBrew(size_t numElements, size_t elementSize)
+{
+    return MALLOC(numElements * elementSize);
+}
+
+static inline void freeBrew(void* p)
+{
+    return FREE(p);
+}
+
+static inline void* reallocBrew(void* p, size_t n)
+{
+    return REALLOC(p, n | ALLOC_NO_ZMEM);
+}
+
+// Use MALLOC macro instead of the standard malloc function.
+// Although RVCT provides malloc, we can't use it in BREW
+// because the loader does not initialize the base address properly.
+#define malloc(n) mallocBrew(n)
+#define calloc(n, s) callocBrew(n, s)
+#define realloc(p, n) reallocBrew(p, n)
+#define free(p) freeBrew(p)
+
+#endif // SystemMallocBrew_h
index b2c507563432616e03384f66a4bd16b146557ecb..39386219d65c1d92cff4a657bfc63c97f598e6bb 100644 (file)
@@ -36,8 +36,7 @@ namespace WTF {
 // An interface to the embedding layer, which provides threading support.
 class ChromiumThreading {
 public:
 // An interface to the embedding layer, which provides threading support.
 class ChromiumThreading {
 public:
-    static void initializeMainThread();
-    static void scheduleDispatchFunctionsOnMainThread();
+    static void callOnMainThread(void (*func)(void*), void* context);
 };
 
 } // namespace WTF
 };
 
 } // namespace WTF
index 394370f026b18a326ca7f4c8521b62812ada8d58..9e6592b5715679ae2bc9a6d1a0b6f3b8c9e18e81 100644 (file)
 #include "config.h"
 #include "MainThread.h"
 
 #include "config.h"
 #include "MainThread.h"
 
+#include "Assertions.h"
 #include "ChromiumThreading.h"
 #include "ChromiumThreading.h"
+#include "Threading.h"
 
 namespace WTF {
 
 
 namespace WTF {
 
-void initializeMainThreadPlatform()
+static ThreadIdentifier mainThreadIdentifier;
+
+void initializeMainThread()
+{
+    static bool initializedMainThread;
+    if (initializedMainThread)
+        return;
+    initializedMainThread = true;
+
+    mainThreadIdentifier = currentThread();
+}
+
+void callOnMainThread(MainThreadFunction* function, void* context)
+{
+    ChromiumThreading::callOnMainThread(function, context);
+}
+
+void callOnMainThreadAndWait(MainThreadFunction*, void*)
+{
+    ASSERT_NOT_REACHED();
+}
+
+void setMainThreadCallbacksPaused(bool)
 {
 {
-    ChromiumThreading::initializeMainThread();
+    ASSERT_NOT_REACHED();
 }
 
 }
 
-void scheduleDispatchFunctionsOnMainThread()
+bool isMainThread()
 {
 {
-    ChromiumThreading::scheduleDispatchFunctionsOnMainThread();
+    return currentThread() == mainThreadIdentifier;
 }
 
 } // namespace WTF
 }
 
 } // namespace WTF
index 6289d0464cb6b16df8a8eeb6d545146de9ebc898..e63be907451a00bb6aa5262d2ce832b92e413339 100644 (file)
 #endif
 
 #define INFNAN_CHECK
 #endif
 
 #define INFNAN_CHECK
+#define No_Hex_NaN
 
 #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) != 1
 Exactly one of IEEE_8087, IEEE_ARM or IEEE_MC68k should be defined.
 
 #if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(IEEE_ARM) != 1
 Exactly one of IEEE_8087, IEEE_ARM or IEEE_MC68k should be defined.
diff --git a/wtf/efl/MainThreadEfl.cpp b/wtf/efl/MainThreadEfl.cpp
new file mode 100644 (file)
index 0000000..fe32d1b
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
+ * Copyright (C) 2008 Diego Gonzalez
+ * Copyright (C) 2008 Kenneth Rohde Christiansen
+ * Copyright (C) 2009-2010 ProFUSION embedded systems
+ * Copyright (C) 2009-2010 Samsung Electronics
+ *
+ * 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 "MainThread.h"
+
+#include <Ecore.h>
+
+namespace WTF {
+
+void initializeMainThreadPlatform()
+{
+}
+
+static int timeoutFired(void*)
+{
+    dispatchFunctionsFromMainThread();
+    return ECORE_CALLBACK_CANCEL;
+}
+
+void scheduleDispatchFunctionsOnMainThread()
+{
+    ecore_timer_add(0, timeoutFired, 0);
+}
+
+
+}
diff --git a/wtf/gobject/GOwnPtr.cpp b/wtf/gobject/GOwnPtr.cpp
new file mode 100644 (file)
index 0000000..da0d839
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008 Collabora Ltd.
+ *
+ *  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 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
+ */
+
+#include "config.h"
+#include "GOwnPtr.h"
+
+#include <gio/gio.h>
+#include <glib.h>
+
+namespace WTF {
+
+template <> void freeOwnedGPtr<GError>(GError* ptr)
+{
+    if (ptr)
+        g_error_free(ptr);
+}
+
+template <> void freeOwnedGPtr<GList>(GList* ptr)
+{
+    g_list_free(ptr);
+}
+
+template <> void freeOwnedGPtr<GCond>(GCond* ptr)
+{
+    if (ptr)
+        g_cond_free(ptr);
+}
+
+template <> void freeOwnedGPtr<GMutex>(GMutex* ptr)
+{
+    if (ptr)
+        g_mutex_free(ptr);
+}
+
+template <> void freeOwnedGPtr<GPatternSpec>(GPatternSpec* ptr)
+{
+    if (ptr)
+        g_pattern_spec_free(ptr);
+}
+
+template <> void freeOwnedGPtr<GDir>(GDir* ptr)
+{
+    if (ptr)
+        g_dir_close(ptr);
+}
+
+template <> void freeOwnedGPtr<GFile>(GFile* ptr)
+{
+    if (ptr)
+        g_object_unref(ptr);
+}
+} // namespace WTF
diff --git a/wtf/gobject/GOwnPtr.h b/wtf/gobject/GOwnPtr.h
new file mode 100644 (file)
index 0000000..1fc594c
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ *  Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *  Copyright (C) 2008 Collabora Ltd.
+ *
+ *  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 GOwnPtr_h
+#define GOwnPtr_h
+
+#include <algorithm>
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+
+// Forward delcarations at this point avoid the need to include GLib includes
+// in WTF headers.
+typedef struct _GError GError;
+typedef struct _GList GList;
+typedef struct _GCond GCond;
+typedef struct _GMutex GMutex;
+typedef struct _GPatternSpec GPatternSpec;
+typedef struct _GDir GDir;
+typedef struct _GHashTable GHashTable;
+typedef struct _GFile GFile;
+extern "C" void g_free(void*);
+
+namespace WTF {
+
+template <typename T> inline void freeOwnedGPtr(T* ptr);
+template<> void freeOwnedGPtr<GError>(GError*);
+template<> void freeOwnedGPtr<GList>(GList*);
+template<> void freeOwnedGPtr<GCond>(GCond*);
+template<> void freeOwnedGPtr<GMutex>(GMutex*);
+template<> void freeOwnedGPtr<GPatternSpec>(GPatternSpec*);
+template<> void freeOwnedGPtr<GDir>(GDir*);
+template<> void freeOwnedGPtr<GHashTable>(GHashTable*);
+template<> void freeOwnedGPtr<GFile>(GFile*);
+
+template <typename T> class GOwnPtr : public Noncopyable {
+public:
+    explicit GOwnPtr(T* ptr = 0) : m_ptr(ptr) { }
+    ~GOwnPtr() { freeOwnedGPtr(m_ptr); }
+
+    T* get() const { return m_ptr; }
+    T* release()
+    {
+        T* ptr = m_ptr;
+        m_ptr = 0;
+        return ptr;
+    }
+
+    T*& outPtr()
+    {
+        ASSERT(!m_ptr);
+        return m_ptr;
+    }
+
+    void set(T* ptr)
+    {
+        ASSERT(!ptr || m_ptr != ptr);
+        freeOwnedGPtr(m_ptr);
+        m_ptr = ptr;
+    }
+
+    void clear()
+    {
+        freeOwnedGPtr(m_ptr);
+        m_ptr = 0;
+    }
+
+    T& operator*() const
+    {
+        ASSERT(m_ptr);
+        return *m_ptr;
+    }
+
+    T* 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 T* GOwnPtr::*UnspecifiedBoolType;
+    operator UnspecifiedBoolType() const { return m_ptr ? &GOwnPtr::m_ptr : 0; }
+
+    void swap(GOwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
+
+private:
+    T* m_ptr;
+};
+
+template <typename T> inline void swap(GOwnPtr<T>& a, GOwnPtr<T>& b)
+{
+    a.swap(b);
+}
+
+template <typename T, typename U> inline bool operator==(const GOwnPtr<T>& a, U* b)
+{ 
+    return a.get() == b; 
+}
+
+template <typename T, typename U> inline bool operator==(T* a, const GOwnPtr<U>& b) 
+{
+    return a == b.get(); 
+}
+
+template <typename T, typename U> inline bool operator!=(const GOwnPtr<T>& a, U* b)
+{
+    return a.get() != b; 
+}
+
+template <typename T, typename U> inline bool operator!=(T* a, const GOwnPtr<U>& b)
+{ 
+    return a != b.get(); 
+}
+
+template <typename T> inline typename GOwnPtr<T>::PtrType getPtr(const GOwnPtr<T>& p)
+{
+    return p.get();
+}
+
+template <typename T> inline void freeOwnedGPtr(T* ptr)
+{
+    g_free(ptr);
+}
+
+} // namespace WTF
+
+using WTF::GOwnPtr;
+
+#endif // GOwnPtr_h
diff --git a/wtf/gobject/GRefPtr.cpp b/wtf/gobject/GRefPtr.cpp
new file mode 100644 (file)
index 0000000..e7cf34b
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 Martin Robinson
+ *
+ *  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 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
+ */
+
+#include "config.h"
+#include "GRefPtr.h"
+
+#include <glib.h>
+
+namespace WTF {
+
+template <> GHashTable* refGPtr(GHashTable* ptr)
+{
+    if (ptr)
+        g_hash_table_ref(ptr);
+    return ptr;
+}
+
+template <> void derefGPtr(GHashTable* ptr)
+{
+    g_hash_table_unref(ptr);
+}
+
+} // namespace WTF
diff --git a/wtf/gobject/GRefPtr.h b/wtf/gobject/GRefPtr.h
new file mode 100644 (file)
index 0000000..3a33605
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *  Copyright (C) 2008 Collabora Ltd.
+ *  Copyright (C) 2009 Martin Robinson
+ *
+ *  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 WTF_GRefPtr_h
+#define WTF_GRefPtr_h
+
+#include "AlwaysInline.h"
+#include <algorithm>
+
+typedef struct _GHashTable GHashTable;
+typedef void* gpointer;
+extern "C" void g_object_unref(gpointer object);
+extern "C" gpointer  g_object_ref_sink(gpointer object);
+
+namespace WTF {
+
+enum GRefPtrAdoptType { GRefPtrAdopt };
+template <typename T> inline T* refGPtr(T*);
+template <typename T> inline void derefGPtr(T*);
+template <typename T> class GRefPtr;
+template <typename T> GRefPtr<T> adoptGRef(T*);
+template <> GHashTable* refGPtr(GHashTable* ptr);
+template <> void derefGPtr(GHashTable* ptr);
+
+template <typename T> class GRefPtr {
+public:
+    GRefPtr() : m_ptr(0) { }
+    GRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) refGPtr(ptr); }
+    GRefPtr(const GRefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) refGPtr(ptr); }
+    template <typename U> GRefPtr(const GRefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) refGPtr(ptr); }
+
+    ~GRefPtr() { if (T* ptr = m_ptr) derefGPtr(ptr); }
+
+    void clear()
+    {
+        if (T* ptr = m_ptr)
+            derefGPtr(ptr);
+        m_ptr = 0;
+    }
+
+    T* get() const { return m_ptr; }
+    T& operator*() const { return *m_ptr; }
+    ALWAYS_INLINE T* operator->() const { return m_ptr; }
+
+    bool operator!() const { return !m_ptr; }
+
+    // This conversion operator allows implicit conversion to bool but not to other integer types.
+    typedef T* GRefPtr::*UnspecifiedBoolType;
+    operator UnspecifiedBoolType() const { return m_ptr ? &GRefPtr::m_ptr : 0; }
+
+    GRefPtr& operator=(const GRefPtr&);
+    GRefPtr& operator=(T*);
+    template <typename U> GRefPtr& operator=(const GRefPtr<U>&);
+
+    void swap(GRefPtr&);
+    friend GRefPtr adoptGRef<T>(T*);
+
+private:
+    static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
+    // Adopting constructor.
+    GRefPtr(T* ptr, GRefPtrAdoptType) : m_ptr(ptr) {}
+
+    T* m_ptr;
+};
+
+template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(const GRefPtr<T>& o)
+{
+    T* optr = o.get();
+    if (optr)
+        refGPtr(optr);
+    T* ptr = m_ptr;
+    m_ptr = optr;
+    if (ptr)
+        derefGPtr(ptr);
+    return *this;
+}
+
+template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(T* optr)
+{
+    T* ptr = m_ptr;
+    if (optr)
+        refGPtr(optr);
+    m_ptr = optr;
+    if (ptr)
+        derefGPtr(ptr);
+    return *this;
+}
+
+template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o)
+{
+    std::swap(m_ptr, o.m_ptr);
+}
+
+template <class T> inline void swap(GRefPtr<T>& a, GRefPtr<T>& b)
+{
+    a.swap(b);
+}
+
+template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, const GRefPtr<U>& b)
+{
+    return a.get() == b.get();
+}
+
+template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, U* b)
+{
+    return a.get() == b;
+}
+
+template <typename T, typename U> inline bool operator==(T* a, const GRefPtr<U>& b)
+{
+    return a == b.get();
+}
+
+template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, const GRefPtr<U>& b)
+{
+    return a.get() != b.get();
+}
+
+template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, U* b)
+{
+    return a.get() != b;
+}
+
+template <typename T, typename U> inline bool operator!=(T* a, const GRefPtr<U>& b)
+{
+    return a != b.get();
+}
+
+template <typename T, typename U> inline GRefPtr<T> static_pointer_cast(const GRefPtr<U>& p)
+{
+    return GRefPtr<T>(static_cast<T*>(p.get()));
+}
+
+template <typename T, typename U> inline GRefPtr<T> const_pointer_cast(const GRefPtr<U>& p)
+{
+    return GRefPtr<T>(const_cast<T*>(p.get()));
+}
+
+template <typename T> inline T* getPtr(const GRefPtr<T>& p)
+{
+    return p.get();
+}
+
+template <typename T> GRefPtr<T> adoptGRef(T* p)
+{
+    return GRefPtr<T>(p, GRefPtrAdopt);
+}
+
+template <typename T> inline T* refGPtr(T* ptr)
+{
+    if (ptr)
+        g_object_ref_sink(ptr);
+    return ptr;
+}
+
+template <typename T> inline void derefGPtr(T* ptr)
+{
+    if (ptr)
+        g_object_unref(ptr);
+}
+
+} // namespace WTF
+
+using WTF::GRefPtr;
+using WTF::refGPtr;
+using WTF::derefGPtr;
+using WTF::adoptGRef;
+using WTF::static_pointer_cast;
+using WTF::const_pointer_cast;
+
+#endif // WTF_GRefPtr_h
diff --git a/wtf/gtk/GOwnPtr.cpp b/wtf/gtk/GOwnPtr.cpp
deleted file mode 100644 (file)
index 1a151b9..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2008 Collabora Ltd.
- *
- *  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 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
- */
-
-#include "config.h"
-#include "GOwnPtr.h"
-
-#include <glib.h>
-
-namespace WTF {
-
-template <> void freeOwnedGPtr<GError>(GError* ptr)
-{
-    if (ptr)
-        g_error_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GList>(GList* ptr)
-{
-    g_list_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GCond>(GCond* ptr)
-{
-    if (ptr)
-        g_cond_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GMutex>(GMutex* ptr)
-{
-    if (ptr)
-        g_mutex_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GPatternSpec>(GPatternSpec* ptr)
-{
-    if (ptr)
-        g_pattern_spec_free(ptr);
-}
-
-template <> void freeOwnedGPtr<GDir>(GDir* ptr)
-{
-    if (ptr)
-        g_dir_close(ptr);
-}
-} // namespace WTF
diff --git a/wtf/gtk/GOwnPtr.h b/wtf/gtk/GOwnPtr.h
deleted file mode 100644 (file)
index ad2c30e..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *  Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- *  Copyright (C) 2008 Collabora Ltd.
- *
- *  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 GOwnPtr_h
-#define GOwnPtr_h
-
-#include <algorithm>
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
-
-// Forward delcarations at this point avoid the need to include GLib includes
-// in WTF headers.
-typedef struct _GError GError;
-typedef struct _GList GList;
-typedef struct _GCond GCond;
-typedef struct _GMutex GMutex;
-typedef struct _GPatternSpec GPatternSpec;
-typedef struct _GDir GDir;
-typedef struct _GHashTable GHashTable;
-extern "C" void g_free(void*);
-
-namespace WTF {
-
-template <typename T> inline void freeOwnedGPtr(T* ptr);
-template<> void freeOwnedGPtr<GError>(GError*);
-template<> void freeOwnedGPtr<GList>(GList*);
-template<> void freeOwnedGPtr<GCond>(GCond*);
-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 : public Noncopyable {
-public:
-    explicit GOwnPtr(T* ptr = 0) : m_ptr(ptr) { }
-    ~GOwnPtr() { freeOwnedGPtr(m_ptr); }
-
-    T* get() const { return m_ptr; }
-    T* release()
-    {
-        T* ptr = m_ptr;
-        m_ptr = 0;
-        return ptr;
-    }
-
-    T*& outPtr()
-    {
-        ASSERT(!m_ptr);
-        return m_ptr;
-    }
-
-    void set(T* ptr)
-    {
-        ASSERT(!ptr || m_ptr != ptr);
-        freeOwnedGPtr(m_ptr);
-        m_ptr = ptr;
-    }
-
-    void clear()
-    {
-        freeOwnedGPtr(m_ptr);
-        m_ptr = 0;
-    }
-
-    T& operator*() const
-    {
-        ASSERT(m_ptr);
-        return *m_ptr;
-    }
-
-    T* 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 T* GOwnPtr::*UnspecifiedBoolType;
-    operator UnspecifiedBoolType() const { return m_ptr ? &GOwnPtr::m_ptr : 0; }
-
-    void swap(GOwnPtr& o) { std::swap(m_ptr, o.m_ptr); }
-
-private:
-    T* m_ptr;
-};
-
-template <typename T> inline void swap(GOwnPtr<T>& a, GOwnPtr<T>& b)
-{
-    a.swap(b);
-}
-
-template <typename T, typename U> inline bool operator==(const GOwnPtr<T>& a, U* b)
-{ 
-    return a.get() == b; 
-}
-
-template <typename T, typename U> inline bool operator==(T* a, const GOwnPtr<U>& b) 
-{
-    return a == b.get(); 
-}
-
-template <typename T, typename U> inline bool operator!=(const GOwnPtr<T>& a, U* b)
-{
-    return a.get() != b; 
-}
-
-template <typename T, typename U> inline bool operator!=(T* a, const GOwnPtr<U>& b)
-{ 
-    return a != b.get(); 
-}
-
-template <typename T> inline typename GOwnPtr<T>::PtrType getPtr(const GOwnPtr<T>& p)
-{
-    return p.get();
-}
-
-template <typename T> inline void freeOwnedGPtr(T* ptr)
-{
-    g_free(ptr);
-}
-
-} // namespace WTF
-
-using WTF::GOwnPtr;
-
-#endif // GOwnPtr_h
diff --git a/wtf/gtk/GRefPtr.cpp b/wtf/gtk/GRefPtr.cpp
deleted file mode 100644 (file)
index e7cf34b..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2009 Martin Robinson
- *
- *  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 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
- */
-
-#include "config.h"
-#include "GRefPtr.h"
-
-#include <glib.h>
-
-namespace WTF {
-
-template <> GHashTable* refGPtr(GHashTable* ptr)
-{
-    if (ptr)
-        g_hash_table_ref(ptr);
-    return ptr;
-}
-
-template <> void derefGPtr(GHashTable* ptr)
-{
-    g_hash_table_unref(ptr);
-}
-
-} // namespace WTF
diff --git a/wtf/gtk/GRefPtr.h b/wtf/gtk/GRefPtr.h
deleted file mode 100644 (file)
index 66739ef..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- *  Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
- *  Copyright (C) 2008 Collabora Ltd.
- *  Copyright (C) 2009 Martin Robinson
- *
- *  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 WTF_GRefPtr_h
-#define WTF_GRefPtr_h
-
-#include "AlwaysInline.h"
-#include <algorithm>
-
-typedef struct _GHashTable GHashTable;
-
-namespace WTF {
-
-enum GRefPtrAdoptType { GRefPtrAdopt };
-template <typename T> inline T* refGPtr(T*);
-template <typename T> inline void derefGPtr(T*);
-template <typename T> class GRefPtr;
-template <typename T> GRefPtr<T> adoptGRef(T*);
-template <> GHashTable* refGPtr(GHashTable* ptr);
-template <> void derefGPtr(GHashTable* ptr);
-
-template <typename T> class GRefPtr {
-public:
-    GRefPtr() : m_ptr(0) { }
-    GRefPtr(T* ptr) : m_ptr(ptr) { if (ptr) refGPtr(ptr); }
-    GRefPtr(const GRefPtr& o) : m_ptr(o.m_ptr) { if (T* ptr = m_ptr) refGPtr(ptr); }
-    template <typename U> GRefPtr(const GRefPtr<U>& o) : m_ptr(o.get()) { if (T* ptr = m_ptr) refGPtr(ptr); }
-
-    ~GRefPtr() { if (T* ptr = m_ptr) derefGPtr(ptr); }
-
-    void clear()
-    {
-        if (T* ptr = m_ptr)
-            derefGPtr(ptr);
-        m_ptr = 0;
-    }
-
-    T* get() const { return m_ptr; }
-    T& operator*() const { return *m_ptr; }
-    ALWAYS_INLINE T* operator->() const { return m_ptr; }
-
-    bool operator!() const { return !m_ptr; }
-
-    // This conversion operator allows implicit conversion to bool but not to other integer types.
-    typedef T* GRefPtr::*UnspecifiedBoolType;
-    operator UnspecifiedBoolType() const { return m_ptr ? &GRefPtr::m_ptr : 0; }
-
-    GRefPtr& operator=(const GRefPtr&);
-    GRefPtr& operator=(T*);
-    template <typename U> GRefPtr& operator=(const GRefPtr<U>&);
-
-    void swap(GRefPtr&);
-    friend GRefPtr adoptGRef<T>(T*);
-
-private:
-    static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); }
-    // Adopting constructor.
-    GRefPtr(T* ptr, GRefPtrAdoptType) : m_ptr(ptr) {}
-
-    T* m_ptr;
-};
-
-template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(const GRefPtr<T>& o)
-{
-    T* optr = o.get();
-    if (optr)
-        refGPtr(optr);
-    T* ptr = m_ptr;
-    m_ptr = optr;
-    if (ptr)
-        derefGPtr(ptr);
-    return *this;
-}
-
-template <typename T> inline GRefPtr<T>& GRefPtr<T>::operator=(T* optr)
-{
-    T* ptr = m_ptr;
-    if (optr)
-        refGPtr(optr);
-    m_ptr = optr;
-    if (ptr)
-        derefGPtr(ptr);
-    return *this;
-}
-
-template <class T> inline void GRefPtr<T>::swap(GRefPtr<T>& o)
-{
-    std::swap(m_ptr, o.m_ptr);
-}
-
-template <class T> inline void swap(GRefPtr<T>& a, GRefPtr<T>& b)
-{
-    a.swap(b);
-}
-
-template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, const GRefPtr<U>& b)
-{
-    return a.get() == b.get();
-}
-
-template <typename T, typename U> inline bool operator==(const GRefPtr<T>& a, U* b)
-{
-    return a.get() == b;
-}
-
-template <typename T, typename U> inline bool operator==(T* a, const GRefPtr<U>& b)
-{
-    return a == b.get();
-}
-
-template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, const GRefPtr<U>& b)
-{
-    return a.get() != b.get();
-}
-
-template <typename T, typename U> inline bool operator!=(const GRefPtr<T>& a, U* b)
-{
-    return a.get() != b;
-}
-
-template <typename T, typename U> inline bool operator!=(T* a, const GRefPtr<U>& b)
-{
-    return a != b.get();
-}
-
-template <typename T, typename U> inline GRefPtr<T> static_pointer_cast(const GRefPtr<U>& p)
-{
-    return GRefPtr<T>(static_cast<T*>(p.get()));
-}
-
-template <typename T, typename U> inline GRefPtr<T> const_pointer_cast(const GRefPtr<U>& p)
-{
-    return GRefPtr<T>(const_cast<T*>(p.get()));
-}
-
-template <typename T> inline T* getPtr(const GRefPtr<T>& p)
-{
-    return p.get();
-}
-
-template <typename T> GRefPtr<T> adoptGRef(T* p)
-{
-    return GRefPtr<T>(p, GRefPtrAdopt);
-}
-
-template <typename T> inline T* refGPtr(T* ptr)
-{
-    if (ptr)
-        g_object_ref_sink(ptr);
-    return ptr;
-}
-
-template <typename T> inline void derefGPtr(T* ptr)
-{
-    if (ptr)
-        g_object_unref(ptr);
-}
-
-} // namespace WTF
-
-using WTF::GRefPtr;
-using WTF::refGPtr;
-using WTF::derefGPtr;
-using WTF::adoptGRef;
-using WTF::static_pointer_cast;
-using WTF::const_pointer_cast;
-
-#endif // WTF_GRefPtr_h
index a6ec8f75cbd7e7f907832a673584b9553d12ff88..0c5cf0c98e3cb6cc77c001777d10390072e59171 100644 (file)
@@ -44,8 +44,6 @@ namespace WTF {
 
 static Mutex* atomicallyInitializedStaticMutex;
 
 
 static Mutex* atomicallyInitializedStaticMutex;
 
-static ThreadIdentifier mainThreadIdentifier;
-
 static Mutex& threadMapMutex()
 {
     static Mutex mutex;
 static Mutex& threadMapMutex()
 {
     static Mutex mutex;
@@ -62,8 +60,6 @@ void initializeThreading()
         atomicallyInitializedStaticMutex = new Mutex;
         threadMapMutex();
         initializeRandomNumberGenerator();
         atomicallyInitializedStaticMutex = new Mutex;
         threadMapMutex();
         initializeRandomNumberGenerator();
-        mainThreadIdentifier = currentThread();
-        initializeMainThread();
     }
 }
 
     }
 }
 
@@ -168,11 +164,6 @@ ThreadIdentifier currentThread()
     return establishIdentifierForThread(currentThread);
 }
 
     return establishIdentifierForThread(currentThread);
 }
 
-bool isMainThread()
-{
-    return currentThread() == mainThreadIdentifier;
-}
-
 Mutex::Mutex()
     : m_mutex(g_mutex_new())
 {
 Mutex::Mutex()
     : m_mutex(g_mutex_new())
 {
index 0ddd5f64ea28a0726792c9ebabf8385c0f8250b5..aabaafa19056d176befab19df275497666d710ce 100644 (file)
 #import "config.h"
 #import "MainThread.h"
 
 #import "config.h"
 #import "MainThread.h"
 
+#import <CoreFoundation/CoreFoundation.h>
 #import <Foundation/NSThread.h>
 #import <Foundation/NSThread.h>
+#import <stdio.h>
 #import <wtf/Assertions.h>
 #import <wtf/Assertions.h>
+#import <wtf/Threading.h>
 
 @interface WTFMainThreadCaller : NSObject {
 }
 
 @interface WTFMainThreadCaller : NSObject {
 }
 
 namespace WTF {
 
 
 namespace WTF {
 
-static WTFMainThreadCaller* staticMainThreadCaller = nil;
-#if USE(WEB_THREAD)
-static NSThread* webThread = nil;
-#endif
+static WTFMainThreadCaller* staticMainThreadCaller;
+static bool isTimerPosted; // This is only accessed on the 'main' thread.
+static bool mainThreadEstablishedAsPthreadMain;
+static pthread_t mainThreadPthread;
+static NSThread* mainThreadNSThread;
 
 void initializeMainThreadPlatform()
 {
 
 void initializeMainThreadPlatform()
 {
+#if !defined(BUILDING_ON_TIGER)
     ASSERT(!staticMainThreadCaller);
     staticMainThreadCaller = [[WTFMainThreadCaller alloc] init];
 
     ASSERT(!staticMainThreadCaller);
     staticMainThreadCaller = [[WTFMainThreadCaller alloc] init];
 
-#if USE(WEB_THREAD)
-    webThread = [[NSThread currentThread] retain];
+    mainThreadEstablishedAsPthreadMain = false;
+    mainThreadPthread = pthread_self();
+    mainThreadNSThread = [[NSThread currentThread] retain];
+#else
+    ASSERT_NOT_REACHED();
 #endif
 }
 
 #endif
 }
 
+void initializeMainThreadToProcessMainThreadPlatform()
+{
+    if (!pthread_main_np())
+        NSLog(@"WebKit Threading Violation - initial use of WebKit from a secondary thread.");
+
+    ASSERT(!staticMainThreadCaller);
+    staticMainThreadCaller = [[WTFMainThreadCaller alloc] init];
+
+    mainThreadEstablishedAsPthreadMain = true;
+    mainThreadPthread = 0;
+    mainThreadNSThread = nil;
+}
+
+static void timerFired(CFRunLoopTimerRef timer, void*)
+{
+    CFRelease(timer);
+    isTimerPosted = false;
+    WTF::dispatchFunctionsFromMainThread();
+}
+
+static void postTimer()
+{
+    ASSERT(isMainThread());
+
+    if (isTimerPosted)
+        return;
+
+    isTimerPosted = true;
+    CFRunLoopAddTimer(CFRunLoopGetCurrent(), CFRunLoopTimerCreate(0, 0, 0, 0, 0, timerFired, 0), kCFRunLoopCommonModes);
+}
+
 void scheduleDispatchFunctionsOnMainThread()
 {
     ASSERT(staticMainThreadCaller);
 void scheduleDispatchFunctionsOnMainThread()
 {
     ASSERT(staticMainThreadCaller);
-#if USE(WEB_THREAD)
-    [staticMainThreadCaller performSelector:@selector(call) onThread:webThread withObject:nil waitUntilDone:NO];
+
+    if (isMainThread()) {
+        postTimer();
+        return;
+    }
+
+    if (mainThreadEstablishedAsPthreadMain) {
+        ASSERT(!mainThreadNSThread);
+        [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
+        return;
+    }
+
+#if !defined(BUILDING_ON_TIGER)
+    ASSERT(mainThreadNSThread);
+    [staticMainThreadCaller performSelector:@selector(call) onThread:mainThreadNSThread withObject:nil waitUntilDone:NO];
 #else
 #else
-    [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO];
+    ASSERT_NOT_REACHED();
 #endif
 }
 
 #endif
 }
 
+bool isMainThread()
+{
+    if (mainThreadEstablishedAsPthreadMain) {
+        ASSERT(!mainThreadPthread);
+        return pthread_main_np();
+    }
+
+#if !defined(BUILDING_ON_TIGER)
+    ASSERT(mainThreadPthread);
+    return pthread_equal(pthread_self(), mainThreadPthread);
+#else
+    ASSERT_NOT_REACHED();
+    return false;
+#endif
+}
+
+// This function is the same as isMainThread() above except that it does not do
+// a ASSERT(mainThreadPthread). This should only be used by code that can get
+// invoked when the WebThread hasn't been started. See <rdar://8502487>.
+bool isWebThread()
+{
+    ASSERT(!mainThreadEstablishedAsPthreadMain);
+    return pthread_equal(pthread_self(), mainThreadPthread);
+}
+
 } // namespace WTF
 } // namespace WTF
index 7b2d0f25a83afdd00a701e5556fb19db1e1c62dc..98b6a0c4d503fdec11739f045605cb3393e46298 100644 (file)
@@ -33,7 +33,7 @@
 
 #include <QtCore/QObject>
 #include <QtCore/QCoreApplication>
 
 #include <QtCore/QObject>
 #include <QtCore/QCoreApplication>
-
+#include <QThread>
 
 namespace WTF {
 
 
 namespace WTF {
 
@@ -67,6 +67,11 @@ void scheduleDispatchFunctionsOnMainThread()
     QMetaObject::invokeMethod(webkit_main_thread_invoker(), "dispatch", Qt::QueuedConnection);
 }
 
     QMetaObject::invokeMethod(webkit_main_thread_invoker(), "dispatch", Qt::QueuedConnection);
 }
 
+bool isMainThread()
+{
+    return QThread::currentThread() == QCoreApplication::instance()->thread();
+}
+
 } // namespace WTF
 
 #include "MainThreadQt.moc"
 } // namespace WTF
 
 #include "MainThreadQt.moc"
diff --git a/wtf/qt/StringQt.cpp b/wtf/qt/StringQt.cpp
new file mode 100644 (file)
index 0000000..b2c621a
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
+ *
+ * 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 COMPUTER, 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 COMPUTER, 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 <wtf/text/WTFString.h>
+
+#include <QString>
+
+namespace WebCore {
+
+// String conversions
+String::String(const QString& qstr)
+{
+    if (qstr.isNull())
+        return;
+    m_impl = StringImpl::create(reinterpret_cast<const UChar*>(qstr.constData()), qstr.length());
+}
+
+String::String(const QStringRef& ref)
+{
+    if (!ref.string())
+        return;
+    m_impl = StringImpl::create(reinterpret_cast<const UChar*>(ref.unicode()), ref.length());
+}
+
+String::operator QString() const
+{
+    return QString(reinterpret_cast<const QChar*>(characters()), length());
+}
+
+QDataStream& operator<<(QDataStream& stream, const String& str)
+{
+    // could be faster
+    stream << QString(str);
+    return stream;
+}
+
+QDataStream& operator>>(QDataStream& stream, String& str)
+{
+    // mabe not the fastest way, but really easy
+    QString tmp;
+    stream >> tmp;
+    str = tmp;
+    return stream;
+}
+
+}
+
+// vim: ts=4 sw=4 et
index dc04a684c35974aa569737d3e7d56b46d0066fe6..7f81646af55acdfcb6763d8b0364f769ee60f142 100644 (file)
@@ -84,8 +84,6 @@ public Q_SLOTS:
 
 static Mutex* atomicallyInitializedStaticMutex;
 
 
 static Mutex* atomicallyInitializedStaticMutex;
 
-static ThreadIdentifier mainThreadIdentifier;
-
 static Mutex& threadMapMutex()
 {
     static Mutex mutex;
 static Mutex& threadMapMutex()
 {
     static Mutex mutex;
@@ -146,11 +144,6 @@ void initializeThreading()
         atomicallyInitializedStaticMutex = new Mutex;
         threadMapMutex();
         initializeRandomNumberGenerator();
         atomicallyInitializedStaticMutex = new Mutex;
         threadMapMutex();
         initializeRandomNumberGenerator();
-        QThread* mainThread = QCoreApplication::instance()->thread();
-        mainThreadIdentifier = identifierByQthreadHandle(mainThread);
-        if (!mainThreadIdentifier)
-            mainThreadIdentifier = establishIdentifierForThread(mainThread);
-        initializeMainThread();
     }
 }
 
     }
 }
 
@@ -215,11 +208,6 @@ ThreadIdentifier currentThread()
     return establishIdentifierForThread(currentThread);
 }
 
     return establishIdentifierForThread(currentThread);
 }
 
-bool isMainThread()
-{
-    return QThread::currentThread() == QCoreApplication::instance()->thread();
-}
-
 Mutex::Mutex()
     : m_mutex(new QMutex())
 {
 Mutex::Mutex()
     : m_mutex(new QMutex())
 {
diff --git a/wtf/symbian/BlockAllocatorSymbian.cpp b/wtf/symbian/BlockAllocatorSymbian.cpp
new file mode 100644 (file)
index 0000000..6a28e9e
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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"
+
+#if OS(SYMBIAN)
+
+#include "BlockAllocatorSymbian.h"
+
+
+namespace WTF {
+
+/** Efficiently allocates blocks of size blockSize with blockSize alignment. 
+ * Primarly designed for JSC Collector's needs. 
+ * Not thread-safe.    
+ */
+AlignedBlockAllocator::AlignedBlockAllocator(TUint32 reservationSize, TUint32 blockSize )
+    : m_reservation(reservationSize), 
+      m_blockSize(blockSize)
+{
+
+     // Get system's page size value.
+     SYMBIAN_PAGESIZE(m_pageSize); 
+     
+     // We only accept multiples of system page size for both initial reservation and the alignment/block size
+     m_reservation = SYMBIAN_ROUNDUPTOMULTIPLE(m_reservation, m_pageSize);
+     __ASSERT_ALWAYS(SYMBIAN_ROUNDUPTOMULTIPLE(m_blockSize, m_pageSize), User::Panic(_L("AlignedBlockAllocator1"), KErrArgument));
+     
+     // Calculate max. bit flags we need to carve a reservationSize range into blockSize-sized blocks
+     m_map.numBits = m_reservation / m_blockSize;   
+     const TUint32 bitsPerWord = 8*sizeof(TUint32); 
+     const TUint32 numWords = (m_map.numBits + bitsPerWord -1) / bitsPerWord; 
+   
+     m_map.bits = new TUint32[numWords];
+     __ASSERT_ALWAYS(m_map.bits, User::Panic(_L("AlignedBlockAllocator2"), KErrNoMemory));
+     m_map.clearAll();
+     
+     // Open a Symbian RChunk, and reserve requested virtual address range   
+     // Any thread in this process can operate this rchunk due to EOwnerProcess access rights. 
+     TInt ret = m_chunk.CreateDisconnectedLocal(0 , 0, (TInt)m_reservation , EOwnerProcess);  
+     if (ret != KErrNone) 
+         User::Panic(_L("AlignedBlockAllocator3"), ret);
+       
+     // This is the offset to m_chunk.Base() required to make it m_blockSize-aligned
+     m_offset = SYMBIAN_ROUNDUPTOMULTIPLE(TUint32(m_chunk.Base()), m_blockSize) - TUint(m_chunk.Base()); 
+
+}
+
+void* AlignedBlockAllocator::alloc()
+{
+
+    TInt  freeRam = 0; 
+    void* address = 0;
+    
+    // Look up first free slot in bit map
+    const TInt freeIdx = m_map.findFree();
+        
+    // Pseudo OOM: We ate up the address space we reserved..
+    // ..even though the device may have free RAM left
+    if (freeIdx < 0)
+        return 0;
+        
+    TInt ret = m_chunk.Commit(m_offset + (m_blockSize * freeIdx), m_blockSize);
+    if (ret != KErrNone)  
+        return 0; // True OOM: Device didn't have physical RAM to spare
+        
+    // Updated bit to mark region as in use. 
+    m_map.set(freeIdx); 
+    
+    // Calculate address of committed region (block)
+    address = (void*)( (m_chunk.Base() + m_offset) + (TUint)(m_blockSize * freeIdx) );
+    
+    return address;
+}
+
+void AlignedBlockAllocator::free(void* block)
+{
+    // Calculate index of block to be freed
+    TInt idx = TUint(static_cast<TUint8*>(block) - m_chunk.Base() - m_offset) / m_blockSize;
+    
+    __ASSERT_DEBUG(idx >= 0 && idx < m_map.numBits, User::Panic(_L("AlignedBlockAllocator4"), KErrCorrupt)); // valid index check
+    __ASSERT_DEBUG(m_map.get(idx), User::Panic(_L("AlignedBlockAllocator5"), KErrCorrupt)); // in-use flag check    
+    
+    // Return committed region to system RAM pool (the physical RAM becomes usable by others)
+    TInt ret = m_chunk.Decommit(m_offset + m_blockSize * idx, m_blockSize);
+            
+    // mark this available again
+    m_map.clear(idx); 
+}
+
+void AlignedBlockAllocator::destroy() 
+{
+    // release everything!
+    m_chunk.Decommit(0, m_chunk.MaxSize());
+    m_map.clearAll();
+}
+
+AlignedBlockAllocator::~AlignedBlockAllocator()
+{
+    destroy();
+    m_chunk.Close();
+    delete [] m_map.bits;
+}
+
+} // end of namespace
+
+#endif // SYMBIAN
diff --git a/wtf/symbian/BlockAllocatorSymbian.h b/wtf/symbian/BlockAllocatorSymbian.h
new file mode 100644 (file)
index 0000000..21422f6
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * 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 BlockAllocatorSymbian_h
+#define BlockAllocatorSymbian_h
+
+#include <e32cmn.h>
+#include <e32std.h>
+#include <hal.h>
+
+
+#define SYMBIAN_PAGESIZE(x) (HAL::Get(HALData::EMemoryPageSize, x));
+#define SYMBIAN_FREERAM(x)  (HAL::Get(HALData::EMemoryRAMFree, x));
+#define SYMBIAN_ROUNDUPTOMULTIPLE(x, multipleof)    ( (x + multipleof - 1) & ~(multipleof - 1) )
+
+// Set sane defaults if -D<flagname=value> wasn't provided via compiler args
+#ifndef JSCCOLLECTOR_VIRTUALMEM_RESERVATION
+#if defined(__WINS__) 
+    // Emulator has limited virtual address space
+    #define JSCCOLLECTOR_VIRTUALMEM_RESERVATION (4*1024*1024)
+#else
+    // HW has plenty of virtual addresses
+    #define JSCCOLLECTOR_VIRTUALMEM_RESERVATION (128*1024*1024)
+#endif
+#endif
+
+namespace WTF {
+
+/** 
+ *  Allocates contiguous region of size blockSize with blockSize-aligned address. 
+ *  blockSize must be a multiple of system page size (typically 4K on Symbian/ARM)
+ *
+ *  @param reservationSize Virtual address range to be reserved upon creation of chunk (bytes).
+ *  @param blockSize Size of a single allocation. Returned address will also be blockSize-aligned.
+ */
+class AlignedBlockAllocator {
+    public:
+        AlignedBlockAllocator(TUint32 reservationSize, TUint32 blockSize);
+        ~AlignedBlockAllocator();
+        void destroy();
+        void* alloc();
+        void free(void* data);
+    
+    private: 
+        RChunk   m_chunk; // Symbian chunk that lets us reserve/commit/decommit
+        TUint    m_offset; // offset of first committed region from base 
+        TInt     m_pageSize; // cached value of system page size, typically 4K on Symbian
+        TUint32  m_reservation;
+        TUint32  m_blockSize;  
+
+        // Tracks comitted/decommitted state of a blockSize region
+        struct {
+            
+            TUint32 *bits; // array of bit flags 
+            TUint32  numBits; // number of regions to keep track of
+            
+            bool get(TUint32 n) const
+            {
+                return !!(bits[n >> 5] & (1 << (n & 0x1F)));
+            }
+            
+            void set(TUint32 n)
+            {
+                bits[n >> 5] |= (1 << (n & 0x1F));
+            }
+            
+            void clear(TUint32 n)
+            {
+                bits[n >> 5] &= ~(1 << (n & 0x1F));
+            }
+            
+            void clearAll()
+            {
+               for (TUint32 i = 0; i < numBits; i++)
+                    clear(i);
+            }
+            
+            TInt findFree() const
+            {
+                for (TUint32 i = 0; i < numBits; i++) {
+                    if (!get(i)) 
+                        return i;
+                }
+                return -1;
+            }
+            
+        } m_map;  
+
+};
+}
+
+#endif // end of BlockAllocatorSymbian_h
+
+
diff --git a/wtf/text/AtomicString.cpp b/wtf/text/AtomicString.cpp
new file mode 100644 (file)
index 0000000..946a6fb
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 <libkern/OSAtomic.h>
+
+#include "AtomicString.h"
+
+#include "StringHash.h"
+#include <wtf/HashSet.h>
+#include <wtf/Threading.h>
+#include <wtf/WTFThreadData.h>
+
+namespace WebCore {
+
+COMPILE_ASSERT(sizeof(AtomicString) == sizeof(String), atomic_string_and_string_must_be_same_size);
+
+class AtomicStringTableLocker {
+    static OSSpinLock s_stringTableLock;
+public:
+    AtomicStringTableLocker() { OSSpinLockLock(&s_stringTableLock); }
+    ~AtomicStringTableLocker() { OSSpinLockUnlock(&s_stringTableLock); }
+};
+OSSpinLock AtomicStringTableLocker::s_stringTableLock = OS_SPINLOCK_INIT;
+
+class AtomicStringTable {
+public:
+    static AtomicStringTable* create()
+    {
+        static AtomicStringTable* sharedStringTable = new AtomicStringTable;
+
+        WTFThreadData& data = wtfThreadData();
+        if (pthread_main_np() || WTF::isWebThread())
+            data.m_atomicStringTable = sharedStringTable;
+        else
+            data.m_atomicStringTable = new AtomicStringTable;
+
+        // The AtomicStringTable is shared between the main UI thread and the
+        // WebThread. We do the following so that its destruction happens only
+        // once - on the main UI thread.
+        if (!WTF::isWebThread())
+            data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
+        return data.m_atomicStringTable;
+    }
+
+    HashSet<StringImpl*>& table()
+    {
+        return m_table;
+    }
+
+private:
+    static void destroy(AtomicStringTable* table)
+    {
+        HashSet<StringImpl*>::iterator end = table->m_table.end();
+        for (HashSet<StringImpl*>::iterator iter = table->m_table.begin(); iter != end; ++iter)
+            (*iter)->setIsAtomic(false);
+        delete table;
+    }
+
+    HashSet<StringImpl*> m_table;
+};
+
+static inline HashSet<StringImpl*>& stringTable()
+{
+    // Once possible we should make this non-lazy (constructed in WTFThreadData's constructor).
+    AtomicStringTable* table = wtfThreadData().atomicStringTable();
+    if (UNLIKELY(!table))
+        table = AtomicStringTable::create();
+    return table->table();
+}
+
+struct CStringTranslator {
+    static unsigned hash(const char* c)
+    {
+        return StringImpl::computeHash(c);
+    }
+
+    static bool equal(StringImpl* r, const char* s)
+    {
+        int length = r->length();
+        const UChar* d = r->characters();
+        for (int i = 0; i != length; ++i) {
+            unsigned char c = s[i];
+            if (d[i] != c)
+                return false;
+        }
+        return s[length] == 0;
+    }
+
+    static void translate(StringImpl*& location, const char* const& c, unsigned hash)
+    {
+        location = StringImpl::create(c).releaseRef(); 
+        location->setHash(hash);
+        location->setIsAtomic(true);
+    }
+};
+
+bool operator==(const AtomicString& a, const char* b)
+{ 
+    StringImpl* impl = a.impl();
+    if ((!impl || !impl->characters()) && !b)
+        return true;
+    if ((!impl || !impl->characters()) || !b)
+        return false;
+    return CStringTranslator::equal(impl, b); 
+}
+
+PassRefPtr<StringImpl> AtomicString::add(const char* c)
+{
+    if (!c)
+        return 0;
+    if (!*c)
+        return StringImpl::empty();    
+    AtomicStringTableLocker locker;
+    pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<const char*, CStringTranslator>(c);
+    if (!addResult.second)
+        return *addResult.first;
+    return adoptRef(*addResult.first);
+}
+
+struct UCharBuffer {
+    const UChar* s;
+    unsigned length;
+};
+
+static inline bool equal(StringImpl* string, const UChar* characters, unsigned length)
+{
+    if (string->length() != length)
+        return false;
+
+    // FIXME: perhaps we should have a more abstract macro that indicates when
+    // going 4 bytes at a time is unsafe
+#if CPU(ARM) || CPU(SH4)
+    const UChar* stringCharacters = string->characters();
+    for (unsigned i = 0; i != length; ++i) {
+        if (*stringCharacters++ != *characters++)
+            return false;
+    }
+    return true;
+#else
+    /* Do it 4-bytes-at-a-time on architectures where it's safe */
+
+    const uint32_t* stringCharacters = reinterpret_cast<const uint32_t*>(string->characters());
+    const uint32_t* bufferCharacters = reinterpret_cast<const uint32_t*>(characters);
+
+    unsigned halfLength = length >> 1;
+    for (unsigned i = 0; i != halfLength; ++i) {
+        if (*stringCharacters++ != *bufferCharacters++)
+            return false;
+    }
+
+    if (length & 1 &&  *reinterpret_cast<const uint16_t*>(stringCharacters) != *reinterpret_cast<const uint16_t*>(bufferCharacters))
+        return false;
+
+    return true;
+#endif
+}
+
+struct UCharBufferTranslator {
+    static unsigned hash(const UCharBuffer& buf)
+    {
+        return StringImpl::computeHash(buf.s, buf.length);
+    }
+
+    static bool equal(StringImpl* const& str, const UCharBuffer& buf)
+    {
+        return WebCore::equal(str, buf.s, buf.length);
+    }
+
+    static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash)
+    {
+        location = StringImpl::create(buf.s, buf.length).releaseRef(); 
+        location->setHash(hash);
+        location->setIsAtomic(true);
+    }
+};
+
+struct HashAndCharacters {
+    unsigned hash;
+    const UChar* characters;
+    unsigned length;
+};
+
+struct HashAndCharactersTranslator {
+    static unsigned hash(const HashAndCharacters& buffer)
+    {
+        ASSERT(buffer.hash == StringImpl::computeHash(buffer.characters, buffer.length));
+        return buffer.hash;
+    }
+
+    static bool equal(StringImpl* const& string, const HashAndCharacters& buffer)
+    {
+        return WebCore::equal(string, buffer.characters, buffer.length);
+    }
+
+    static void translate(StringImpl*& location, const HashAndCharacters& buffer, unsigned hash)
+    {
+        location = StringImpl::create(buffer.characters, buffer.length).releaseRef();
+        location->setHash(hash);
+        location->setIsAtomic(true);
+    }
+};
+
+PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length)
+{
+    if (!s)
+        return 0;
+
+    if (length == 0)
+        return StringImpl::empty();
+    
+    UCharBuffer buf = { s, length }; 
+    AtomicStringTableLocker locker;
+    pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<UCharBuffer, UCharBufferTranslator>(buf);
+
+    // If the string is newly-translated, then we need to adopt it.
+    // The boolean in the pair tells us if that is so.
+    return addResult.second ? adoptRef(*addResult.first) : *addResult.first;
+}
+
+PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length, unsigned existingHash)
+{
+    ASSERT(s);
+    ASSERT(existingHash);
+
+    if (length == 0)
+        return StringImpl::empty();
+    
+    HashAndCharacters buffer = { existingHash, s, length }; 
+    AtomicStringTableLocker locker;
+    pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<HashAndCharacters, HashAndCharactersTranslator>(buffer);
+    if (!addResult.second)
+        return *addResult.first;
+    return adoptRef(*addResult.first);
+}
+
+PassRefPtr<StringImpl> AtomicString::add(const UChar* s)
+{
+    if (!s)
+        return 0;
+
+    int length = 0;
+    while (s[length] != UChar(0))
+        length++;
+
+    if (length == 0)
+        return StringImpl::empty();
+
+    UCharBuffer buf = {s, length}; 
+    AtomicStringTableLocker locker;
+    pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<UCharBuffer, UCharBufferTranslator>(buf);
+
+    // If the string is newly-translated, then we need to adopt it.
+    // The boolean in the pair tells us if that is so.
+    return addResult.second ? adoptRef(*addResult.first) : *addResult.first;
+}
+
+PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* r)
+{
+    if (!r || r->isAtomic())
+        return r;
+
+    if (r->length() == 0)
+        return StringImpl::empty();
+
+    AtomicStringTableLocker locker;
+    StringImpl* result = *stringTable().add(r).first;
+    if (result == r)
+        r->setIsAtomic(true);
+    return result;
+}
+
+AtomicStringImpl* AtomicString::find(const UChar* s, unsigned length, unsigned existingHash)
+{
+    ASSERT(s);
+    ASSERT(existingHash);
+
+    if (length == 0)
+        return static_cast<AtomicStringImpl*>(StringImpl::empty());
+
+    HashAndCharacters buffer = { existingHash, s, length }; 
+    AtomicStringTableLocker locker;
+    HashSet<StringImpl*>::iterator iterator = stringTable().find<HashAndCharacters, HashAndCharactersTranslator>(buffer);
+    if (iterator == stringTable().end())
+        return 0;
+    return static_cast<AtomicStringImpl*>(*iterator);
+}
+
+void AtomicString::remove(StringImpl* r)
+{
+    AtomicStringTableLocker locker;
+    stringTable().remove(r);
+}
+    
+AtomicString AtomicString::lower() const
+{
+    // Note: This is a hot function in the Dromaeo benchmark.
+    StringImpl* impl = this->impl();
+    RefPtr<StringImpl> newImpl = impl->lower();
+    if (LIKELY(newImpl == impl))
+        return *this;
+    return AtomicString(newImpl);
+}
+
+}
diff --git a/wtf/text/AtomicString.h b/wtf/text/AtomicString.h
new file mode 100644 (file)
index 0000000..5bb2cf9
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2004, 2005, 2006, 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 AtomicString_h
+#define AtomicString_h
+
+#include "AtomicStringImpl.h"
+#include "WTFString.h"
+
+// Define 'NO_IMPLICIT_ATOMICSTRING' before including this header,
+// to disallow (expensive) implicit String-->AtomicString conversions.
+#ifdef NO_IMPLICIT_ATOMICSTRING
+#define ATOMICSTRING_CONVERSION explicit
+#else
+#define ATOMICSTRING_CONVERSION
+#endif
+
+// FIXME: This is a temporary layering violation while we move string code to WTF.
+// Landing the file moves in one patch, will follow on with patches to change the namespaces.
+namespace WebCore {
+
+struct AtomicStringHash;
+
+class AtomicString {
+public:
+    static void init();
+
+    AtomicString() { }
+    AtomicString(const char* s) : m_string(add(s)) { }
+    AtomicString(const UChar* s, unsigned length) : m_string(add(s, length)) { }
+    AtomicString(const UChar* s, unsigned length, unsigned existingHash) : m_string(add(s, length, existingHash)) { }
+    AtomicString(const UChar* s) : m_string(add(s)) { }
+    ATOMICSTRING_CONVERSION AtomicString(StringImpl* imp) : m_string(add(imp)) { }
+    AtomicString(AtomicStringImpl* imp) : m_string(imp) { }
+    ATOMICSTRING_CONVERSION AtomicString(const String& s) : m_string(add(s.impl())) { }
+
+    // Hash table deleted values, which are only constructed and never copied or destroyed.
+    AtomicString(WTF::HashTableDeletedValueType) : m_string(WTF::HashTableDeletedValue) { }
+    bool isHashTableDeletedValue() const { return m_string.isHashTableDeletedValue(); }
+
+    static AtomicStringImpl* find(const UChar* s, unsigned length, unsigned existingHash);
+
+    operator const String&() const { return m_string; }
+    const String& string() const { return m_string; };
+
+    AtomicStringImpl* impl() const { return static_cast<AtomicStringImpl *>(m_string.impl()); }
+    
+    const UChar* characters() const { return m_string.characters(); }
+    unsigned length() const { return m_string.length(); }
+    
+    UChar operator[](unsigned int i) const { return m_string[i]; }
+    
+    bool contains(UChar c) const { return m_string.contains(c); }
+    bool contains(const char* s, bool caseSensitive = true) const
+        { return m_string.contains(s, caseSensitive); }
+    bool contains(const String& s, bool caseSensitive = true) const
+        { return m_string.contains(s, caseSensitive); }
+
+    int find(UChar c, int start = 0) const { return m_string.find(c, start); }
+    int find(const char* s, int start = 0, bool caseSentitive = true) const
+        { return m_string.find(s, start, caseSentitive); }
+    int find(const String& s, int start = 0, bool caseSentitive = true) const
+        { return m_string.find(s, start, caseSentitive); }
+    
+    bool startsWith(const String& s, bool caseSensitive = true) const
+        { return m_string.startsWith(s, caseSensitive); }
+    bool endsWith(const String& s, bool caseSensitive = true) const
+        { return m_string.endsWith(s, caseSensitive); }
+    
+    AtomicString lower() const;
+    AtomicString upper() const { return AtomicString(impl()->upper()); }
+    
+    int toInt(bool* ok = 0) const { return m_string.toInt(ok); }
+    double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); }
+    float toFloat(bool* ok = 0) const { return m_string.toFloat(ok); }
+    bool percentage(int& p) const { return m_string.percentage(p); }
+
+    bool isNull() const { return m_string.isNull(); }
+    bool isEmpty() const { return m_string.isEmpty(); }
+
+    static void remove(StringImpl*);
+    
+#if PLATFORM(CF)
+    AtomicString(CFStringRef s) :  m_string(add(String(s).impl())) { }
+    CFStringRef createCFString() const { return m_string.createCFString(); }
+#endif    
+#ifdef __OBJC__
+    AtomicString(NSString* s) : m_string(add(String(s).impl())) { }
+    operator NSString*() const { return m_string; }
+#endif
+#if PLATFORM(QT)
+    AtomicString(const QString& s) : m_string(add(String(s).impl())) { }
+    operator QString() const { return m_string; }
+#endif
+
+private:
+    String m_string;
+    
+    static PassRefPtr<StringImpl> add(const char*);
+    static PassRefPtr<StringImpl> add(const UChar*, unsigned length);
+    static PassRefPtr<StringImpl> add(const UChar*, unsigned length, unsigned existingHash);
+    static PassRefPtr<StringImpl> add(const UChar*);
+    ALWAYS_INLINE PassRefPtr<StringImpl> add(StringImpl* r)
+    {
+        if (!r || r->isAtomic())
+            return r;
+        return addSlowCase(r);
+    }
+    static PassRefPtr<StringImpl> addSlowCase(StringImpl*);
+};
+
+inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); }
+bool operator==(const AtomicString& a, const char* b);
+inline bool operator==(const AtomicString& a, const String& b) { return equal(a.impl(), b.impl()); }
+inline bool operator==(const char* a, const AtomicString& b) { return b == a; }
+inline bool operator==(const String& a, const AtomicString& b) { return equal(a.impl(), b.impl()); }
+
+inline bool operator!=(const AtomicString& a, const AtomicString& b) { return a.impl() != b.impl(); }
+inline bool operator!=(const AtomicString& a, const char *b) { return !(a == b); }
+inline bool operator!=(const AtomicString& a, const String& b) { return !equal(a.impl(), b.impl()); }
+inline bool operator!=(const char* a, const AtomicString& b) { return !(b == a); }
+inline bool operator!=(const String& a, const AtomicString& b) { return !equal(a.impl(), b.impl()); }
+
+inline bool equalIgnoringCase(const AtomicString& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); }
+inline bool equalIgnoringCase(const AtomicString& a, const char* b) { return equalIgnoringCase(a.impl(), b); }
+inline bool equalIgnoringCase(const AtomicString& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); }
+inline bool equalIgnoringCase(const char* a, const AtomicString& b) { return equalIgnoringCase(a, b.impl()); }
+inline bool equalIgnoringCase(const String& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); }
+
+// Define external global variables for the commonly used atomic strings.
+// These are only usable from the main thread.
+#ifndef ATOMICSTRING_HIDE_GLOBALS
+    extern const JS_EXPORTDATA AtomicString nullAtom;
+    extern const JS_EXPORTDATA AtomicString emptyAtom;
+    extern const JS_EXPORTDATA AtomicString textAtom;
+    extern const JS_EXPORTDATA AtomicString commentAtom;
+    extern const JS_EXPORTDATA AtomicString starAtom;
+    extern const JS_EXPORTDATA AtomicString xmlAtom;
+    extern const JS_EXPORTDATA AtomicString xmlnsAtom;
+#endif
+
+} // namespace WebCore
+
+
+namespace WTF {
+
+    // AtomicStringHash is the default hash for AtomicString
+    template<typename T> struct DefaultHash;
+    template<> struct DefaultHash<WebCore::AtomicString> {
+        typedef WebCore::AtomicStringHash Hash;
+    };
+
+} // namespace WTF
+
+#endif // AtomicString_h
diff --git a/wtf/text/AtomicStringImpl.h b/wtf/text/AtomicStringImpl.h
new file mode 100644 (file)
index 0000000..4b813f8
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2006 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
+ * 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 AtomicStringImpl_h
+#define AtomicStringImpl_h
+
+#include "StringImpl.h"
+
+// FIXME: This is a temporary layering violation while we move string code to WTF.
+// Landing the file moves in one patch, will follow on with patches to change the namespaces.
+namespace WebCore {
+
+class AtomicStringImpl : public StringImpl
+{
+public:
+    AtomicStringImpl() : StringImpl(0) {}
+};
+
+}
+
+#endif
diff --git a/wtf/text/CString.cpp b/wtf/text/CString.cpp
new file mode 100644 (file)
index 0000000..7d09f12
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2003, 2006, 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
+ * 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 COMPUTER, 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 COMPUTER, 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 "CString.h"
+
+using std::min;
+
+namespace WTF {
+
+CString::CString(const char* str)
+{
+    init(str, strlen(str));
+}
+
+CString::CString(const char* str, unsigned length)
+{
+    init(str, length);
+}
+
+void CString::init(const char* str, unsigned length)
+{
+    if (!str)
+        return;
+    
+    m_buffer = CStringBuffer::create(length + 1);
+    memcpy(m_buffer->mutableData(), str, length); 
+    m_buffer->mutableData()[length] = '\0';
+}
+
+char* CString::mutableData()
+{
+    copyBufferIfNeeded();
+    if (!m_buffer)
+        return 0;
+    return m_buffer->mutableData();
+}
+    
+CString CString::newUninitialized(size_t length, char*& characterBuffer)
+{
+    CString result;
+    result.m_buffer = CStringBuffer::create(length + 1);
+    char* bytes = result.m_buffer->mutableData();
+    bytes[length] = '\0';
+    characterBuffer = bytes;
+    return result;
+}
+
+void CString::copyBufferIfNeeded()
+{
+    if (!m_buffer || m_buffer->hasOneRef())
+        return;
+        
+    int len = m_buffer->length();
+    RefPtr<CStringBuffer> m_temp = m_buffer;
+    m_buffer = CStringBuffer::create(len);
+    memcpy(m_buffer->mutableData(), m_temp->data(), len);
+}
+
+bool operator==(const CString& a, const CString& b)
+{
+    if (a.isNull() != b.isNull())
+        return false;
+    if (a.length() != b.length())
+        return false;
+    return !strncmp(a.data(), b.data(), min(a.length(), b.length()));
+}
+
+} // namespace WTF
diff --git a/wtf/text/CString.h b/wtf/text/CString.h
new file mode 100644 (file)
index 0000000..d8250c5
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2003, 2006, 2008, 2009, 2010 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 COMPUTER, 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 COMPUTER, 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 CString_h
+#define CString_h
+
+#include "PassRefPtr.h"
+#include "RefCounted.h"
+#include "Vector.h"
+
+namespace WTF {
+
+class CStringBuffer : public RefCounted<CStringBuffer> {
+public:
+    const char* data() { return m_vector.data(); }
+    size_t length() { return m_vector.size(); }
+
+private:
+    friend class CString;
+
+    static PassRefPtr<CStringBuffer> create(unsigned length) { return adoptRef(new CStringBuffer(length)); }
+    CStringBuffer(unsigned length) : m_vector(length) { }
+    char* mutableData() { return m_vector.data(); }
+
+    Vector<char> m_vector;
+};
+
+// A container for a null-terminated char array supporting copy-on-write
+// assignment.  The contained char array may be null.
+class CString {
+public:
+    CString() { }
+    CString(const char*);
+    CString(const char*, unsigned length);
+    CString(CStringBuffer* buffer) : m_buffer(buffer) { }
+    static CString newUninitialized(size_t length, char*& characterBuffer);
+
+    const char* data() const
+    {
+        return m_buffer ? m_buffer->data() : 0;
+    }
+    char* mutableData();
+    unsigned length() const
+    {
+        return m_buffer ? m_buffer->length() - 1 : 0;
+    }
+
+    bool isNull() const { return !m_buffer; }
+
+    CStringBuffer* buffer() const { return m_buffer.get(); }
+
+private:
+    void copyBufferIfNeeded();
+    void init(const char*, unsigned length);
+    RefPtr<CStringBuffer> m_buffer;
+};
+
+bool operator==(const CString& a, const CString& b);
+inline bool operator!=(const CString& a, const CString& b) { return !(a == b); }
+
+} // namespace WTF
+
+using WTF::CString;
+
+#endif // CString_h
diff --git a/wtf/text/StringBuffer.h b/wtf/text/StringBuffer.h
new file mode 100644 (file)
index 0000000..cf732e3
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008, 2010 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 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 StringBuffer_h
+#define StringBuffer_h
+
+#include <wtf/Assertions.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/unicode/Unicode.h>
+#include <limits>
+
+namespace WebCore {
+
+class StringBuffer : public Noncopyable {
+public:
+    explicit StringBuffer(unsigned length)
+        : m_length(length)
+    {
+        if (m_length > std::numeric_limits<unsigned>::max() / sizeof(UChar))
+            CRASH();
+        m_data = static_cast<UChar*>(fastMalloc(m_length * sizeof(UChar)));
+    }
+
+    ~StringBuffer()
+    {
+        fastFree(m_data);
+    }
+
+    void shrink(unsigned newLength)
+    {
+        ASSERT(newLength <= m_length);
+        m_length = newLength;
+    }
+
+    void resize(unsigned newLength)
+    {
+        if (newLength > m_length) {
+            if (newLength > std::numeric_limits<unsigned>::max() / sizeof(UChar))
+                CRASH();
+            m_data = static_cast<UChar*>(fastRealloc(m_data, newLength * sizeof(UChar)));
+        }
+        m_length = newLength;
+    }
+
+    unsigned length() const { return m_length; }
+    UChar* characters() { return m_data; }
+
+    UChar& operator[](unsigned i) { ASSERT(i < m_length); return m_data[i]; }
+
+    UChar* release() { UChar* data = m_data; m_data = 0; return data; }
+
+private:
+    unsigned m_length;
+    UChar* m_data;
+};
+
+} // namespace WTF
+
+#endif // StringBuffer_h
diff --git a/wtf/text/StringHash.h b/wtf/text/StringHash.h
new file mode 100644 (file)
index 0000000..b820004
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved
+ * Copyright (C) Research In Motion Limited 2009. 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 StringHash_h
+#define StringHash_h
+
+#include "AtomicString.h"
+#include "WTFString.h"
+#include <wtf/HashTraits.h>
+#include <wtf/StringHashFunctions.h>
+#include <wtf/unicode/Unicode.h>
+
+// FIXME: This is a temporary layering violation while we move string code to WTF.
+// Landing the file moves in one patch, will follow on with patches to change the namespaces.
+namespace WebCore {
+
+    // The hash() functions on StringHash and CaseFoldingHash do not support
+    // null strings. get(), contains(), and add() on HashMap<String,..., StringHash>
+    // cause a null-pointer dereference when passed null strings.
+
+    // FIXME: We should really figure out a way to put the computeHash function that's
+    // currently a member function of StringImpl into this file so we can be a little
+    // closer to having all the nearly-identical hash functions in one place.
+
+    struct StringHash {
+        static unsigned hash(StringImpl* key) { return key->hash(); }
+        static bool equal(const StringImpl* a, const StringImpl* b)
+        {
+            if (a == b)
+                return true;
+            if (!a || !b)
+                return false;
+
+            unsigned aLength = a->length();
+            unsigned bLength = b->length();
+            if (aLength != bLength)
+                return false;
+
+            // FIXME: perhaps we should have a more abstract macro that indicates when
+            // going 4 bytes at a time is unsafe
+#if CPU(ARM) || CPU(SH4)
+            const UChar* aChars = a->characters();
+            const UChar* bChars = b->characters();
+            for (unsigned i = 0; i != aLength; ++i) {
+                if (*aChars++ != *bChars++)
+                    return false;
+            }
+            return true;
+#else
+            /* Do it 4-bytes-at-a-time on architectures where it's safe */
+            const uint32_t* aChars = reinterpret_cast<const uint32_t*>(a->characters());
+            const uint32_t* bChars = reinterpret_cast<const uint32_t*>(b->characters());
+
+            unsigned halfLength = aLength >> 1;
+            for (unsigned i = 0; i != halfLength; ++i)
+                if (*aChars++ != *bChars++)
+                    return false;
+
+            if (aLength & 1 && *reinterpret_cast<const uint16_t*>(aChars) != *reinterpret_cast<const uint16_t*>(bChars))
+                return false;
+
+            return true;
+#endif
+        }
+
+        static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); }
+        static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b)
+        {
+            return equal(a.get(), b.get());
+        }
+
+        static unsigned hash(const String& key) { return key.impl()->hash(); }
+        static bool equal(const String& a, const String& b)
+        {
+            return equal(a.impl(), b.impl());
+        }
+
+        static const bool safeToCompareToEmptyOrDeleted = false;
+    };
+
+    class CaseFoldingHash {
+    public:
+        // Paul Hsieh's SuperFastHash
+        // http://www.azillionmonkeys.com/qed/hash.html
+        static unsigned hash(const UChar* data, unsigned length)
+        {
+            unsigned l = length;
+            const UChar* s = data;
+            uint32_t hash = WTF::stringHashingStartValue;
+            uint32_t tmp;
+            
+            int rem = l & 1;
+            l >>= 1;
+            
+            // Main loop.
+            for (; l > 0; l--) {
+                hash += WTF::Unicode::foldCase(s[0]);
+                tmp = (WTF::Unicode::foldCase(s[1]) << 11) ^ hash;
+                hash = (hash << 16) ^ tmp;
+                s += 2;
+                hash += hash >> 11;
+            }
+            
+            // Handle end case.
+            if (rem) {
+                hash += WTF::Unicode::foldCase(s[0]);
+                hash ^= hash << 11;
+                hash += hash >> 17;
+            }
+            
+            // Force "avalanching" of final 127 bits.
+            hash ^= hash << 3;
+            hash += hash >> 5;
+            hash ^= hash << 2;
+            hash += hash >> 15;
+            hash ^= hash << 10;
+            
+            // This avoids ever returning a hash code of 0, since that is used to
+            // signal "hash not computed yet", using a value that is likely to be
+            // effectively the same as 0 when the low bits are masked.
+            hash |= !hash << 31;
+            
+            return hash;
+        }
+
+        static unsigned hash(StringImpl* str)
+        {
+            return hash(str->characters(), str->length());
+        }
+        
+        static unsigned hash(const char* str, unsigned length)
+        {
+            // This hash is designed to work on 16-bit chunks at a time. But since the normal case
+            // (above) is to hash UTF-16 characters, we just treat the 8-bit chars as if they
+            // were 16-bit chunks, which will give matching results.
+
+            unsigned l = length;
+            const char* s = str;
+            uint32_t hash = WTF::stringHashingStartValue;
+            uint32_t tmp;
+            
+            int rem = l & 1;
+            l >>= 1;
+            
+            // Main loop
+            for (; l > 0; l--) {
+                hash += WTF::Unicode::foldCase(s[0]);
+                tmp = (WTF::Unicode::foldCase(s[1]) << 11) ^ hash;
+                hash = (hash << 16) ^ tmp;
+                s += 2;
+                hash += hash >> 11;
+            }
+            
+            // Handle end case
+            if (rem) {
+                hash += WTF::Unicode::foldCase(s[0]);
+                hash ^= hash << 11;
+                hash += hash >> 17;
+            }
+            
+            // Force "avalanching" of final 127 bits
+            hash ^= hash << 3;
+            hash += hash >> 5;
+            hash ^= hash << 2;
+            hash += hash >> 15;
+            hash ^= hash << 10;
+            
+            // this avoids ever returning a hash code of 0, since that is used to
+            // signal "hash not computed yet", using a value that is likely to be
+            // effectively the same as 0 when the low bits are masked
+            hash |= !hash << 31;
+            
+            return hash;
+        }
+        
+        static bool equal(const StringImpl* a, const StringImpl* b)
+        {
+            if (a == b)
+                return true;
+            if (!a || !b)
+                return false;
+            unsigned length = a->length();
+            if (length != b->length())
+                return false;
+            return WTF::Unicode::umemcasecmp(a->characters(), b->characters(), length) == 0;
+        }
+
+        static unsigned hash(const RefPtr<StringImpl>& key) 
+        {
+            return hash(key.get());
+        }
+
+        static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b)
+        {
+            return equal(a.get(), b.get());
+        }
+
+        static unsigned hash(const String& key)
+        {
+            return hash(key.impl());
+        }
+        static unsigned hash(const AtomicString& key)
+        {
+            return hash(key.impl());
+        }
+        static bool equal(const String& a, const String& b)
+        {
+            return equal(a.impl(), b.impl());
+        }
+        static bool equal(const AtomicString& a, const AtomicString& b)
+        {
+            return (a == b) || equal(a.impl(), b.impl());
+        }
+
+        static const bool safeToCompareToEmptyOrDeleted = false;
+    };
+
+    // This hash can be used in cases where the key is a hash of a string, but we don't
+    // want to store the string. It's not really specific to string hashing, but all our
+    // current uses of it are for strings.
+    struct AlreadyHashed : IntHash<unsigned> {
+        static unsigned hash(unsigned key) { return key; }
+
+        // To use a hash value as a key for a hash table, we need to eliminate the
+        // "deleted" value, which is negative one. That could be done by changing
+        // the string hash function to never generate negative one, but this works
+        // and is still relatively efficient.
+        static unsigned avoidDeletedValue(unsigned hash)
+        {
+            ASSERT(hash);
+            unsigned newHash = hash | (!(hash + 1) << 31);
+            ASSERT(newHash);
+            ASSERT(newHash != 0xFFFFFFFF);
+            return newHash;
+        }
+    };
+
+}
+
+namespace WTF {
+
+    template<> struct HashTraits<WebCore::String> : GenericHashTraits<WebCore::String> {
+        static const bool emptyValueIsZero = true;
+        static void constructDeletedValue(WebCore::String& slot) { new (&slot) WebCore::String(HashTableDeletedValue); }
+        static bool isDeletedValue(const WebCore::String& slot) { return slot.isHashTableDeletedValue(); }
+    };
+
+}
+
+#endif
diff --git a/wtf/text/StringImpl.cpp b/wtf/text/StringImpl.cpp
new file mode 100644 (file)
index 0000000..41a6610
--- /dev/null
@@ -0,0 +1,981 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller ( mueller@kde.org )
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net)
+ *
+ * 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 "StringImpl.h"
+
+#include "AtomicString.h"
+#include "StringBuffer.h"
+#include "StringHash.h"
+#include <wtf/StdLibExtras.h>
+#include <wtf/WTFThreadData.h>
+
+using namespace WTF;
+using namespace Unicode;
+using namespace std;
+
+namespace WebCore {
+
+static const unsigned minLengthToShare = 20;
+
+StringImpl::~StringImpl()
+{
+    ASSERT(!isStatic());
+
+    if (isAtomic())
+        AtomicString::remove(this);
+#if USE(JSC)
+    if (isIdentifier())
+        wtfThreadData().currentIdentifierTable()->remove(this);
+#endif
+
+    BufferOwnership ownership = bufferOwnership();
+    if (ownership != BufferInternal) {
+        if (ownership == BufferOwned) {
+            ASSERT(!m_sharedBuffer);
+            ASSERT(m_data);
+            fastFree(const_cast<UChar*>(m_data));
+        } else if (ownership == BufferSubstring) {
+            ASSERT(m_substringBuffer);
+            m_substringBuffer->deref();
+        } else {
+            ASSERT(ownership == BufferShared);
+            ASSERT(m_sharedBuffer);
+            m_sharedBuffer->deref();
+        }
+    }
+}
+
+PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data)
+{
+    if (!length) {
+        data = 0;
+        return empty();
+    }
+
+    // Allocate a single buffer large enough to contain the StringImpl
+    // struct as well as the data which it contains. This removes one 
+    // heap allocation from this call.
+    if (length > ((std::numeric_limits<size_t>::max() - sizeof(StringImpl)) / sizeof(UChar)))
+        CRASH();
+    size_t size = sizeof(StringImpl) + length * sizeof(UChar);
+    StringImpl* string = static_cast<StringImpl*>(fastMalloc(size));
+
+    data = reinterpret_cast<UChar*>(string + 1);
+    return adoptRef(new (string) StringImpl(length));
+}
+
+PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length)
+{
+    if (!characters || !length)
+        return empty();
+
+    UChar* data;
+    PassRefPtr<StringImpl> string = createUninitialized(length, data);
+    memcpy(data, characters, length * sizeof(UChar));
+    return string;
+}
+
+PassRefPtr<StringImpl> StringImpl::create(const char* characters, unsigned length)
+{
+    if (!characters || !length)
+        return empty();
+
+    UChar* data;
+    PassRefPtr<StringImpl> string = createUninitialized(length, data);
+    for (unsigned i = 0; i != length; ++i) {
+        unsigned char c = characters[i];
+        data[i] = c;
+    }
+    return string;
+}
+
+PassRefPtr<StringImpl> StringImpl::create(const char* string)
+{
+    if (!string)
+        return empty();
+    return create(string, strlen(string));
+}
+
+PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
+{
+    ASSERT(characters);
+    ASSERT(minLengthToShare && length >= minLengthToShare);
+    return adoptRef(new StringImpl(characters, length, sharedBuffer));
+}
+
+SharedUChar* StringImpl::sharedBuffer()
+{
+    if (m_length < minLengthToShare)
+        return 0;
+    // All static strings are smaller that the minimim length to share.
+    ASSERT(!isStatic());
+
+    BufferOwnership ownership = bufferOwnership();
+
+    if (ownership == BufferInternal)
+        return 0;
+    if (ownership == BufferSubstring)
+        return m_substringBuffer->sharedBuffer();
+    if (ownership == BufferOwned) {
+        ASSERT(!m_sharedBuffer);
+        m_sharedBuffer = SharedUChar::create(new SharableUChar(m_data)).releaseRef();
+        m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared;
+    }
+
+    ASSERT(bufferOwnership() == BufferShared);
+    ASSERT(m_sharedBuffer);
+    return m_sharedBuffer;
+}
+
+bool StringImpl::containsOnlyWhitespace()
+{
+    // FIXME: The definition of whitespace here includes a number of characters
+    // that are not whitespace from the point of view of RenderText; I wonder if
+    // that's a problem in practice.
+    for (unsigned i = 0; i < m_length; i++)
+        if (!isASCIISpace(m_data[i]))
+            return false;
+    return true;
+}
+
+PassRefPtr<StringImpl> StringImpl::substring(unsigned start, unsigned length)
+{
+    if (start >= m_length)
+        return empty();
+    unsigned maxLength = m_length - start;
+    if (length >= maxLength) {
+        if (!start)
+            return this;
+        length = maxLength;
+    }
+    return create(m_data + start, length);
+}
+
+UChar32 StringImpl::characterStartingAt(unsigned i)
+{
+    if (U16_IS_SINGLE(m_data[i]))
+        return m_data[i];
+    if (i + 1 < m_length && U16_IS_LEAD(m_data[i]) && U16_IS_TRAIL(m_data[i + 1]))
+        return U16_GET_SUPPLEMENTARY(m_data[i], m_data[i + 1]);
+    return 0;
+}
+
+PassRefPtr<StringImpl> StringImpl::lower()
+{
+    // Note: This is a hot function in the Dromaeo benchmark, specifically the
+    // no-op code path up through the first 'return' statement.
+    
+    // First scan the string for uppercase and non-ASCII characters:
+    UChar ored = 0;
+    bool noUpper = true;
+    const UChar *end = m_data + m_length;
+    for (const UChar* chp = m_data; chp != end; chp++) {
+        if (UNLIKELY(isASCIIUpper(*chp)))
+            noUpper = false;
+        ored |= *chp;
+    }
+    
+    // Nothing to do if the string is all ASCII with no uppercase.
+    if (noUpper && !(ored & ~0x7F))
+        return this;
+
+    int32_t length = m_length;
+    UChar* data;
+    RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
+
+    if (!(ored & ~0x7F)) {
+        // Do a faster loop for the case where all the characters are ASCII.
+        for (int i = 0; i < length; i++) {
+            UChar c = m_data[i];
+            data[i] = toASCIILower(c);
+        }
+        return newImpl;
+    }
+    
+    // Do a slower implementation for cases that include non-ASCII characters.
+    bool error;
+    int32_t realLength = Unicode::toLower(data, length, m_data, m_length, &error);
+    if (!error && realLength == length)
+        return newImpl;
+    newImpl = createUninitialized(realLength, data);
+    Unicode::toLower(data, realLength, m_data, m_length, &error);
+    if (error)
+        return this;
+    return newImpl;
+}
+
+PassRefPtr<StringImpl> StringImpl::upper()
+{
+    // This function could be optimized for no-op cases the way lower() is,
+    // but in empirical testing, few actual calls to upper() are no-ops, so
+    // it wouldn't be worth the extra time for pre-scanning.
+    UChar* data;
+    PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
+    int32_t length = m_length;
+
+    // Do a faster loop for the case where all the characters are ASCII.
+    UChar ored = 0;
+    for (int i = 0; i < length; i++) {
+        UChar c = m_data[i];
+        ored |= c;
+        data[i] = toASCIIUpper(c);
+    }
+    if (!(ored & ~0x7F))
+        return newImpl;
+
+    // Do a slower implementation for cases that include non-ASCII characters.
+    bool error;
+    int32_t realLength = Unicode::toUpper(data, length, m_data, m_length, &error);
+    if (!error && realLength == length)
+        return newImpl;
+    newImpl = createUninitialized(realLength, data);
+    Unicode::toUpper(data, realLength, m_data, m_length, &error);
+    if (error)
+        return this;
+    return newImpl;
+}
+
+PassRefPtr<StringImpl> StringImpl::secure(UChar aChar, bool last)
+{
+    int length = m_length;
+    Vector<UChar> data(length);
+    if (length > 0) {
+        for (int i = 0; i <  length - 1; ++i)
+            data[i] = aChar;
+        data[length - 1] = (last ? aChar : m_data[length - 1]);
+    }
+    return adopt(data);
+}
+
+PassRefPtr<StringImpl> StringImpl::foldCase()
+{
+    UChar* data;
+    PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
+    int32_t length = m_length;
+
+    // Do a faster loop for the case where all the characters are ASCII.
+    UChar ored = 0;
+    for (int i = 0; i < length; i++) {
+        UChar c = m_data[i];
+        ored |= c;
+        data[i] = toASCIILower(c);
+    }
+    if (!(ored & ~0x7F))
+        return newImpl;
+
+    // Do a slower implementation for cases that include non-ASCII characters.
+    bool error;
+    int32_t realLength = Unicode::foldCase(data, length, m_data, m_length, &error);
+    if (!error && realLength == length)
+        return newImpl;
+    newImpl = createUninitialized(realLength, data);
+    Unicode::foldCase(data, realLength, m_data, m_length, &error);
+    if (error)
+        return this;
+    return newImpl;
+}
+
+PassRefPtr<StringImpl> StringImpl::stripWhiteSpace()
+{
+    if (!m_length)
+        return empty();
+
+    unsigned start = 0;
+    unsigned end = m_length - 1;
+    
+    // skip white space from start
+    while (start <= end && isSpaceOrNewline(m_data[start]))
+        start++;
+    
+    // only white space
+    if (start > end) 
+        return empty();
+
+    // skip white space from end
+    while (end && isSpaceOrNewline(m_data[end]))
+        end--;
+
+    if (!start && end == m_length - 1)
+        return this;
+    return create(m_data + start, end + 1 - start);
+}
+
+PassRefPtr<StringImpl> StringImpl::removeCharacters(CharacterMatchFunctionPtr findMatch)
+{
+    const UChar* from = m_data;
+    const UChar* fromend = from + m_length;
+
+    // Assume the common case will not remove any characters
+    while (from != fromend && !findMatch(*from))
+        from++;
+    if (from == fromend)
+        return this;
+
+    StringBuffer data(m_length);
+    UChar* to = data.characters();
+    unsigned outc = from - m_data;
+
+    if (outc)
+        memcpy(to, m_data, outc * sizeof(UChar));
+
+    while (true) {
+        while (from != fromend && findMatch(*from))
+            from++;
+        while (from != fromend && !findMatch(*from))
+            to[outc++] = *from++;
+        if (from == fromend)
+            break;
+    }
+
+    data.shrink(outc);
+
+    return adopt(data);
+}
+
+PassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace()
+{
+    StringBuffer data(m_length);
+
+    const UChar* from = m_data;
+    const UChar* fromend = from + m_length;
+    int outc = 0;
+    bool changedToSpace = false;
+    
+    UChar* to = data.characters();
+    
+    while (true) {
+        while (from != fromend && isSpaceOrNewline(*from)) {
+            if (*from != ' ')
+                changedToSpace = true;
+            from++;
+        }
+        while (from != fromend && !isSpaceOrNewline(*from))
+            to[outc++] = *from++;
+        if (from != fromend)
+            to[outc++] = ' ';
+        else
+            break;
+    }
+    
+    if (outc > 0 && to[outc - 1] == ' ')
+        outc--;
+    
+    if (static_cast<unsigned>(outc) == m_length && !changedToSpace)
+        return this;
+    
+    data.shrink(outc);
+    
+    return adopt(data);
+}
+
+int StringImpl::toIntStrict(bool* ok, int base)
+{
+    return charactersToIntStrict(m_data, m_length, ok, base);
+}
+
+unsigned StringImpl::toUIntStrict(bool* ok, int base)
+{
+    return charactersToUIntStrict(m_data, m_length, ok, base);
+}
+
+int64_t StringImpl::toInt64Strict(bool* ok, int base)
+{
+    return charactersToInt64Strict(m_data, m_length, ok, base);
+}
+
+uint64_t StringImpl::toUInt64Strict(bool* ok, int base)
+{
+    return charactersToUInt64Strict(m_data, m_length, ok, base);
+}
+
+intptr_t StringImpl::toIntPtrStrict(bool* ok, int base)
+{
+    return charactersToIntPtrStrict(m_data, m_length, ok, base);
+}
+
+int StringImpl::toInt(bool* ok)
+{
+    return charactersToInt(m_data, m_length, ok);
+}
+
+unsigned StringImpl::toUInt(bool* ok)
+{
+    return charactersToUInt(m_data, m_length, ok);
+}
+
+int64_t StringImpl::toInt64(bool* ok)
+{
+    return charactersToInt64(m_data, m_length, ok);
+}
+
+uint64_t StringImpl::toUInt64(bool* ok)
+{
+    return charactersToUInt64(m_data, m_length, ok);
+}
+
+intptr_t StringImpl::toIntPtr(bool* ok)
+{
+    return charactersToIntPtr(m_data, m_length, ok);
+}
+
+double StringImpl::toDouble(bool* ok)
+{
+    return charactersToDouble(m_data, m_length, ok);
+}
+
+float StringImpl::toFloat(bool* ok)
+{
+    return charactersToFloat(m_data, m_length, ok);
+}
+
+static bool equal(const UChar* a, const char* b, int length)
+{
+    ASSERT(length >= 0);
+    while (length--) {
+        unsigned char bc = *b++;
+        if (*a++ != bc)
+            return false;
+    }
+    return true;
+}
+
+bool equalIgnoringCase(const UChar* a, const char* b, unsigned length)
+{
+    while (length--) {
+        unsigned char bc = *b++;
+        if (foldCase(*a++) != foldCase(bc))
+            return false;
+    }
+    return true;
+}
+
+static inline bool equalIgnoringCase(const UChar* a, const UChar* b, int length)
+{
+    ASSERT(length >= 0);
+    return umemcasecmp(a, b, length) == 0;
+}
+
+int StringImpl::find(const char* chs, int index, bool caseSensitive)
+{
+    if (!chs || index < 0)
+        return -1;
+
+    int chsLength = strlen(chs);
+    int n = m_length - index;
+    if (n < 0)
+        return -1;
+    n -= chsLength - 1;
+    if (n <= 0)
+        return -1;
+
+    const char* chsPlusOne = chs + 1;
+    int chsLengthMinusOne = chsLength - 1;
+    
+    const UChar* ptr = m_data + index - 1;
+    if (caseSensitive) {
+        UChar c = *chs;
+        do {
+            if (*++ptr == c && equal(ptr + 1, chsPlusOne, chsLengthMinusOne))
+                return m_length - chsLength - n + 1;
+        } while (--n);
+    } else {
+        UChar lc = Unicode::foldCase(*chs);
+        do {
+            if (Unicode::foldCase(*++ptr) == lc && equalIgnoringCase(ptr + 1, chsPlusOne, chsLengthMinusOne))
+                return m_length - chsLength - n + 1;
+        } while (--n);
+    }
+
+    return -1;
+}
+
+int StringImpl::find(UChar c, int start)
+{
+    return WebCore::find(m_data, m_length, c, start);
+}
+
+int StringImpl::find(CharacterMatchFunctionPtr matchFunction, int start)
+{
+    return WebCore::find(m_data, m_length, matchFunction, start);
+}
+
+int StringImpl::find(StringImpl* str, int index, bool caseSensitive)
+{
+    /*
+      We use a simple trick for efficiency's sake. Instead of
+      comparing strings, we compare the sum of str with that of
+      a part of this string. Only if that matches, we call memcmp
+      or ucstrnicmp.
+    */
+    ASSERT(str);
+    if (index < 0)
+        index += m_length;
+    int lstr = str->m_length;
+    int lthis = m_length - index;
+    if ((unsigned)lthis > m_length)
+        return -1;
+    int delta = lthis - lstr;
+    if (delta < 0)
+        return -1;
+
+    const UChar* uthis = m_data + index;
+    const UChar* ustr = str->m_data;
+    unsigned hthis = 0;
+    unsigned hstr = 0;
+    if (caseSensitive) {
+        for (int i = 0; i < lstr; i++) {
+            hthis += uthis[i];
+            hstr += ustr[i];
+        }
+        int i = 0;
+        while (1) {
+            if (hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(UChar)) == 0)
+                return index + i;
+            if (i == delta)
+                return -1;
+            hthis += uthis[i + lstr];
+            hthis -= uthis[i];
+            i++;
+        }
+    } else {
+        for (int i = 0; i < lstr; i++ ) {
+            hthis += toASCIILower(uthis[i]);
+            hstr += toASCIILower(ustr[i]);
+        }
+        int i = 0;
+        while (1) {
+            if (hthis == hstr && equalIgnoringCase(uthis + i, ustr, lstr))
+                return index + i;
+            if (i == delta)
+                return -1;
+            hthis += toASCIILower(uthis[i + lstr]);
+            hthis -= toASCIILower(uthis[i]);
+            i++;
+        }
+    }
+}
+
+int StringImpl::reverseFind(UChar c, int index)
+{
+    return WebCore::reverseFind(m_data, m_length, c, index);
+}
+
+int StringImpl::reverseFind(StringImpl* str, int index, bool caseSensitive)
+{
+    /*
+     See StringImpl::find() for explanations.
+     */
+    ASSERT(str);
+    int lthis = m_length;
+    if (index < 0)
+        index += lthis;
+    
+    int lstr = str->m_length;
+    int delta = lthis - lstr;
+    if ( index < 0 || index > lthis || delta < 0 )
+        return -1;
+    if ( index > delta )
+        index = delta;
+    
+    const UChar *uthis = m_data;
+    const UChar *ustr = str->m_data;
+    unsigned hthis = 0;
+    unsigned hstr = 0;
+    int i;
+    if (caseSensitive) {
+        for ( i = 0; i < lstr; i++ ) {
+            hthis += uthis[index + i];
+            hstr += ustr[i];
+        }
+        i = index;
+        while (1) {
+            if (hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(UChar)) == 0)
+                return i;
+            if (i == 0)
+                return -1;
+            i--;
+            hthis -= uthis[i + lstr];
+            hthis += uthis[i];
+        }
+    } else {
+        for (i = 0; i < lstr; i++) {
+            hthis += toASCIILower(uthis[index + i]);
+            hstr += toASCIILower(ustr[i]);
+        }
+        i = index;
+        while (1) {
+            if (hthis == hstr && equalIgnoringCase(uthis + i, ustr, lstr) )
+                return i;
+            if (i == 0)
+                return -1;
+            i--;
+            hthis -= toASCIILower(uthis[i + lstr]);
+            hthis += toASCIILower(uthis[i]);
+        }
+    }
+    
+    // Should never get here.
+    return -1;
+}
+
+bool StringImpl::endsWith(StringImpl* m_data, bool caseSensitive)
+{
+    ASSERT(m_data);
+    int start = m_length - m_data->m_length;
+    if (start >= 0)
+        return (find(m_data, start, caseSensitive) == start);
+    return false;
+}
+
+PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC)
+{
+    if (oldC == newC)
+        return this;
+    unsigned i;
+    for (i = 0; i != m_length; ++i)
+        if (m_data[i] == oldC)
+            break;
+    if (i == m_length)
+        return this;
+
+    UChar* data;
+    PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
+
+    for (i = 0; i != m_length; ++i) {
+        UChar ch = m_data[i];
+        if (ch == oldC)
+            ch = newC;
+        data[i] = ch;
+    }
+    return newImpl;
+}
+
+PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToReplace, StringImpl* str)
+{
+    position = min(position, length());
+    lengthToReplace = min(lengthToReplace, length() - position);
+    unsigned lengthToInsert = str ? str->length() : 0;
+    if (!lengthToReplace && !lengthToInsert)
+        return this;
+    UChar* data;
+
+    if ((length() - lengthToReplace) >= (numeric_limits<unsigned>::max() - lengthToInsert))
+        CRASH();
+
+    PassRefPtr<StringImpl> newImpl =
+        createUninitialized(length() - lengthToReplace + lengthToInsert, data);
+    memcpy(data, characters(), position * sizeof(UChar));
+    if (str)
+        memcpy(data + position, str->characters(), lengthToInsert * sizeof(UChar));
+    memcpy(data + position + lengthToInsert, characters() + position + lengthToReplace,
+        (length() - position - lengthToReplace) * sizeof(UChar));
+    return newImpl;
+}
+
+PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacement)
+{
+    if (!replacement)
+        return this;
+        
+    int repStrLength = replacement->length();
+    int srcSegmentStart = 0;
+    unsigned matchCount = 0;
+    
+    // Count the matches
+    while ((srcSegmentStart = find(pattern, srcSegmentStart)) >= 0) {
+        ++matchCount;
+        ++srcSegmentStart;
+    }
+    
+    // If we have 0 matches, we don't have to do any more work
+    if (!matchCount)
+        return this;
+    
+    if (repStrLength && matchCount > numeric_limits<unsigned>::max() / repStrLength)
+        CRASH();
+
+    unsigned replaceSize = matchCount * repStrLength;
+    unsigned newSize = m_length - matchCount;
+    if (newSize >= (numeric_limits<unsigned>::max() - replaceSize))
+        CRASH();
+
+    newSize += replaceSize;
+
+    UChar* data;
+    PassRefPtr<StringImpl> newImpl = createUninitialized(newSize, data);
+
+    // Construct the new data
+    int srcSegmentEnd;
+    int srcSegmentLength;
+    srcSegmentStart = 0;
+    int dstOffset = 0;
+    
+    while ((srcSegmentEnd = find(pattern, srcSegmentStart)) >= 0) {
+        srcSegmentLength = srcSegmentEnd - srcSegmentStart;
+        memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar));
+        dstOffset += srcSegmentLength;
+        memcpy(data + dstOffset, replacement->m_data, repStrLength * sizeof(UChar));
+        dstOffset += repStrLength;
+        srcSegmentStart = srcSegmentEnd + 1;
+    }
+
+    srcSegmentLength = m_length - srcSegmentStart;
+    memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar));
+
+    ASSERT(dstOffset + srcSegmentLength == static_cast<int>(newImpl->length()));
+
+    return newImpl;
+}
+
+PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* replacement)
+{
+    if (!pattern || !replacement)
+        return this;
+
+    int patternLength = pattern->length();
+    if (!patternLength)
+        return this;
+        
+    int repStrLength = replacement->length();
+    int srcSegmentStart = 0;
+    unsigned matchCount = 0;
+    
+    // Count the matches
+    while ((srcSegmentStart = find(pattern, srcSegmentStart)) >= 0) {
+        ++matchCount;
+        srcSegmentStart += patternLength;
+    }
+    
+    // If we have 0 matches, we don't have to do any more work
+    if (!matchCount)
+        return this;
+    
+    unsigned newSize = m_length - matchCount * patternLength;
+    if (repStrLength && matchCount > numeric_limits<unsigned>::max() / repStrLength)
+        CRASH();
+
+    if (newSize > (numeric_limits<unsigned>::max() - matchCount * repStrLength))
+        CRASH();
+
+    newSize += matchCount * repStrLength;
+
+    UChar* data;
+    PassRefPtr<StringImpl> newImpl = createUninitialized(newSize, data);
+    
+    // Construct the new data
+    int srcSegmentEnd;
+    int srcSegmentLength;
+    srcSegmentStart = 0;
+    int dstOffset = 0;
+    
+    while ((srcSegmentEnd = find(pattern, srcSegmentStart)) >= 0) {
+        srcSegmentLength = srcSegmentEnd - srcSegmentStart;
+        memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar));
+        dstOffset += srcSegmentLength;
+        memcpy(data + dstOffset, replacement->m_data, repStrLength * sizeof(UChar));
+        dstOffset += repStrLength;
+        srcSegmentStart = srcSegmentEnd + patternLength;
+    }
+
+    srcSegmentLength = m_length - srcSegmentStart;
+    memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar));
+
+    ASSERT(dstOffset + srcSegmentLength == static_cast<int>(newImpl->length()));
+
+    return newImpl;
+}
+
+bool equal(const StringImpl* a, const StringImpl* b)
+{
+    return StringHash::equal(a, b);
+}
+
+bool equal(const StringImpl* a, const char* b)
+{
+    if (!a)
+        return !b;
+    if (!b)
+        return !a;
+
+    unsigned length = a->length();
+    const UChar* as = a->characters();
+    for (unsigned i = 0; i != length; ++i) {
+        unsigned char bc = b[i];
+        if (!bc)
+            return false;
+        if (as[i] != bc)
+            return false;
+    }
+
+    return !b[length];
+}
+
+bool equalIgnoringCase(StringImpl* a, StringImpl* b)
+{
+    return CaseFoldingHash::equal(a, b);
+}
+
+bool equalIgnoringCase(StringImpl* a, const char* b)
+{
+    if (!a)
+        return !b;
+    if (!b)
+        return !a;
+
+    unsigned length = a->length();
+    const UChar* as = a->characters();
+
+    // Do a faster loop for the case where all the characters are ASCII.
+    UChar ored = 0;
+    bool equal = true;
+    for (unsigned i = 0; i != length; ++i) {
+        char bc = b[i];
+        if (!bc)
+            return false;
+        UChar ac = as[i];
+        ored |= ac;
+        equal = equal && (toASCIILower(ac) == toASCIILower(bc));
+    }
+
+    // Do a slower implementation for cases that include non-ASCII characters.
+    if (ored & ~0x7F) {
+        equal = true;
+        for (unsigned i = 0; i != length; ++i) {
+            unsigned char bc = b[i];
+            equal = equal && (foldCase(as[i]) == foldCase(bc));
+        }
+    }
+
+    return equal && !b[length];
+}
+
+bool equalIgnoringNullity(StringImpl* a, StringImpl* b)
+{
+    if (StringHash::equal(a, b))
+        return true;
+    if (!a && b && !b->length())
+        return true;
+    if (!b && a && !a->length())
+        return true;
+
+    return false;
+}
+
+Vector<char> StringImpl::ascii()
+{
+    Vector<char> buffer(m_length + 1);
+    for (unsigned i = 0; i != m_length; ++i) {
+        UChar c = m_data[i];
+        if ((c >= 0x20 && c < 0x7F) || c == 0x00)
+            buffer[i] = static_cast<char>(c);
+        else
+            buffer[i] = '?';
+    }
+    buffer[m_length] = '\0';
+    return buffer;
+}
+
+WTF::Unicode::Direction StringImpl::defaultWritingDirection()
+{
+    for (unsigned i = 0; i < m_length; ++i) {
+        WTF::Unicode::Direction charDirection = WTF::Unicode::direction(m_data[i]);
+        if (charDirection == WTF::Unicode::LeftToRight)
+            return WTF::Unicode::LeftToRight;
+        if (charDirection == WTF::Unicode::RightToLeft || charDirection == WTF::Unicode::RightToLeftArabic)
+            return WTF::Unicode::RightToLeft;
+    }
+    return WTF::Unicode::LeftToRight;
+}
+
+// This is a hot function because it's used when parsing HTML.
+PassRefPtr<StringImpl> StringImpl::createStrippingNullCharactersSlowCase(const UChar* characters, unsigned length)
+{
+    StringBuffer strippedCopy(length);
+    unsigned strippedLength = 0;
+    for (unsigned i = 0; i < length; i++) {
+        if (int c = characters[i])
+            strippedCopy[strippedLength++] = c;
+    }
+    ASSERT(strippedLength < length);  // Only take the slow case when stripping.
+    strippedCopy.shrink(strippedLength);
+    return adopt(strippedCopy);
+}
+
+PassRefPtr<StringImpl> StringImpl::adopt(StringBuffer& buffer)
+{
+    unsigned length = buffer.length();
+    if (length == 0)
+        return empty();
+    return adoptRef(new StringImpl(buffer.release(), length));
+}
+
+int StringImpl::wordCount(int maxWordsToCount)
+{
+    unsigned wordCount = 0;
+    unsigned i;
+    bool atWord = false;
+    for (i = 0; i < m_length; i++) {
+        if (u_isspace(m_data[i])) {
+            atWord = false;
+        } else if (!atWord) {
+            wordCount++;
+            if (wordCount >= (unsigned)maxWordsToCount)
+                return wordCount;
+            atWord = true;
+        }
+    }
+    return wordCount;
+}
+
+PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string)
+{
+    // Use createUninitialized instead of 'new StringImpl' so that the string and its buffer
+    // get allocated in a single malloc block.
+    UChar* data;
+    int length = string.m_length;
+    RefPtr<StringImpl> terminatedString = createUninitialized(length + 1, data);
+    memcpy(data, string.m_data, length * sizeof(UChar));
+    data[length] = 0;
+    terminatedString->m_length--;
+    terminatedString->m_hash = string.m_hash;
+    terminatedString->m_refCountAndFlags |= s_refCountFlagHasTerminatingNullCharacter;
+    return terminatedString.release();
+}
+
+PassRefPtr<StringImpl> StringImpl::threadsafeCopy() const
+{
+    return create(m_data, m_length);
+}
+
+PassRefPtr<StringImpl> StringImpl::crossThreadString()
+{
+    if (SharedUChar* sharedBuffer = this->sharedBuffer())
+        return adoptRef(new StringImpl(m_data, m_length, sharedBuffer->crossThreadCopy()));
+
+    // If no shared buffer is available, create a copy.
+    return threadsafeCopy();
+}
+
+} // namespace WebCore
diff --git a/wtf/text/StringImpl.h b/wtf/text/StringImpl.h
new file mode 100644 (file)
index 0000000..0a02382
--- /dev/null
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 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 StringImpl_h
+#define StringImpl_h
+
+#include <limits.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/CrossThreadRefCounted.h>
+#include <wtf/OwnFastMallocPtr.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/StringHashFunctions.h>
+#include <wtf/Vector.h>
+#include <wtf/text/StringImplBase.h>
+#include <wtf/unicode/Unicode.h>
+
+#if PLATFORM(CF)
+typedef const struct __CFString * CFStringRef;
+#endif
+
+#ifdef __OBJC__
+@class NSString;
+#endif
+
+// FIXME: This is a temporary layering violation while we move string code to WTF.
+// Landing the file moves in one patch, will follow on with patches to change the namespaces.
+namespace JSC {
+
+struct IdentifierCStringTranslator;
+struct IdentifierUCharBufferTranslator;
+
+}
+
+// FIXME: This is a temporary layering violation while we move string code to WTF.
+// Landing the file moves in one patch, will follow on with patches to change the namespaces.
+namespace WebCore {
+
+class StringBuffer;
+
+struct CStringTranslator;
+struct HashAndCharactersTranslator;
+struct StringHash;
+struct UCharBufferTranslator;
+
+enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive };
+
+typedef OwnFastMallocPtr<const UChar> SharableUChar;
+typedef CrossThreadRefCounted<SharableUChar> SharedUChar;
+typedef bool (*CharacterMatchFunctionPtr)(UChar);
+
+class StringImpl : public StringImplBase {
+    friend struct JSC::IdentifierCStringTranslator;
+    friend struct JSC::IdentifierUCharBufferTranslator;
+    friend struct CStringTranslator;
+    friend struct HashAndCharactersTranslator;
+    friend struct UCharBufferTranslator;
+    friend class AtomicStringImpl;
+private:
+    // Used to construct static strings, which have an special refCount that can never hit zero.
+    // This means that the static string will never be destroyed, which is important because
+    // static strings will be shared across threads & ref-counted in a non-threadsafe manner.
+    StringImpl(const UChar* characters, unsigned length, StaticStringConstructType)
+        : StringImplBase(length, ConstructStaticString)
+        , m_data(characters)
+        , m_buffer(0)
+        , m_hash(0)
+    {
+        // Ensure that the hash is computed so that AtomicStringHash can call existingHash()
+        // with impunity. The empty string is special because it is never entered into
+        // AtomicString's HashKey, but still needs to compare correctly.
+        hash();
+    }
+
+    // Create a normal string with internal storage (BufferInternal)
+    StringImpl(unsigned length)
+        : StringImplBase(length, BufferInternal)
+        , m_data(reinterpret_cast<const UChar*>(this + 1))
+        , m_buffer(0)
+        , m_hash(0)
+    {
+        ASSERT(m_data);
+        ASSERT(m_length);
+    }
+
+    // Create a StringImpl adopting ownership of the provided buffer (BufferOwned)
+    StringImpl(const UChar* characters, unsigned length)
+        : StringImplBase(length, BufferOwned)
+        , m_data(characters)
+        , m_buffer(0)
+        , m_hash(0)
+    {
+        ASSERT(m_data);
+        ASSERT(m_length);
+    }
+
+    // Used to create new strings that are a substring of an existing StringImpl (BufferSubstring)
+    StringImpl(const UChar* characters, unsigned length, PassRefPtr<StringImpl> base)
+        : StringImplBase(length, BufferSubstring)
+        , m_data(characters)
+        , m_substringBuffer(base.releaseRef())
+        , m_hash(0)
+    {
+        ASSERT(m_data);
+        ASSERT(m_length);
+        ASSERT(m_substringBuffer->bufferOwnership() != BufferSubstring);
+    }
+
+    // Used to construct new strings sharing an existing SharedUChar (BufferShared)
+    StringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
+        : StringImplBase(length, BufferShared)
+        , m_data(characters)
+        , m_sharedBuffer(sharedBuffer.releaseRef())
+        , m_hash(0)
+    {
+        ASSERT(m_data);
+        ASSERT(m_length);
+    }
+
+    // For use only by AtomicString's XXXTranslator helpers.
+    void setHash(unsigned hash)
+    {
+        ASSERT(!isStatic());
+        ASSERT(!m_hash);
+        ASSERT(hash == computeHash(m_data, m_length));
+        m_hash = hash;
+    }
+
+public:
+    ~StringImpl();
+
+    static PassRefPtr<StringImpl> create(const UChar*, unsigned length);
+    static PassRefPtr<StringImpl> create(const char*, unsigned length);
+    static PassRefPtr<StringImpl> create(const char*);
+    static PassRefPtr<StringImpl> create(const UChar*, unsigned length, PassRefPtr<SharedUChar> sharedBuffer);
+    static PassRefPtr<StringImpl> create(PassRefPtr<StringImpl> rep, unsigned offset, unsigned length)
+    {
+        ASSERT(rep);
+        ASSERT(length <= rep->length());
+
+        if (!length)
+            return empty();
+
+        StringImpl* ownerRep = (rep->bufferOwnership() == BufferSubstring) ? rep->m_substringBuffer : rep.get();
+        return adoptRef(new StringImpl(rep->m_data + offset, length, ownerRep));
+    }
+
+    static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data);
+    static PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, UChar*& output)
+    {
+        if (!length) {
+            output = 0;
+            return empty();
+        }
+
+        if (length > ((std::numeric_limits<size_t>::max() - sizeof(StringImpl)) / sizeof(UChar)))
+            return 0;
+        StringImpl* resultImpl;
+        if (!tryFastMalloc(sizeof(UChar) * length + sizeof(StringImpl)).getValue(resultImpl))
+            return 0;
+        output = reinterpret_cast<UChar*>(resultImpl + 1);
+        return adoptRef(new(resultImpl) StringImpl(length));
+    }
+
+    static unsigned dataOffset() { return OBJECT_OFFSETOF(StringImpl, m_data); }
+    static PassRefPtr<StringImpl> createWithTerminatingNullCharacter(const StringImpl&);
+    static PassRefPtr<StringImpl> createStrippingNullCharacters(const UChar*, unsigned length);
+
+    template<size_t inlineCapacity>
+    static PassRefPtr<StringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
+    {
+        if (size_t size = vector.size()) {
+            ASSERT(vector.data());
+            return adoptRef(new StringImpl(vector.releaseBuffer(), size));
+        }
+        return empty();
+    }
+    static PassRefPtr<StringImpl> adopt(StringBuffer&);
+
+    SharedUChar* sharedBuffer();
+    const UChar* characters() const { return m_data; }
+
+    size_t cost()
+    {
+        // For substrings, return the cost of the base string.
+        if (bufferOwnership() == BufferSubstring)
+            return m_substringBuffer->cost();
+
+        if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) {
+            m_refCountAndFlags &= ~s_refCountFlagShouldReportedCost;
+            return m_length;
+        }
+        return 0;
+    }
+
+    bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; }
+    void setIsIdentifier(bool isIdentifier)
+    {
+        ASSERT(!isStatic());
+        if (isIdentifier)
+            m_refCountAndFlags |= s_refCountFlagIsIdentifier;
+        else
+            m_refCountAndFlags &= ~s_refCountFlagIsIdentifier;
+    }
+
+    bool hasTerminatingNullCharacter() const { return m_refCountAndFlags & s_refCountFlagHasTerminatingNullCharacter; }
+
+    bool isAtomic() const { return m_refCountAndFlags & s_refCountFlagIsAtomic; }
+    void setIsAtomic(bool isIdentifier)
+    {
+        ASSERT(!isStatic());
+        if (isIdentifier)
+            m_refCountAndFlags |= s_refCountFlagIsAtomic;
+        else
+            m_refCountAndFlags &= ~s_refCountFlagIsAtomic;
+    }
+
+    unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; }
+    unsigned existingHash() const { ASSERT(m_hash); return m_hash; }
+    static unsigned computeHash(const UChar* data, unsigned length) { return WTF::stringHash(data, length); }
+    static unsigned computeHash(const char* data, unsigned length) { return WTF::stringHash(data, length); }
+    static unsigned computeHash(const char* data) { return WTF::stringHash(data); }
+
+    ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; }
+    ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic)) == s_refCountIncrement; }
+
+    static StringImpl* empty();
+
+    static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters)
+    {
+        if (numCharacters <= s_copyCharsInlineCutOff) {
+            for (unsigned i = 0; i < numCharacters; ++i)
+                destination[i] = source[i];
+        } else
+            memcpy(destination, source, numCharacters * sizeof(UChar));
+    }
+
+    // Returns a StringImpl suitable for use on another thread.
+    PassRefPtr<StringImpl> crossThreadString();
+    // Makes a deep copy. Helpful only if you need to use a String on another thread
+    // (use crossThreadString if the method call doesn't need to be threadsafe).
+    // Since StringImpl objects are immutable, there's no other reason to make a copy.
+    PassRefPtr<StringImpl> threadsafeCopy() const;
+
+    PassRefPtr<StringImpl> substring(unsigned pos, unsigned len = UINT_MAX);
+
+    UChar operator[](unsigned i) { ASSERT(i < m_length); return m_data[i]; }
+    UChar32 characterStartingAt(unsigned);
+
+    bool containsOnlyWhitespace();
+
+    int toIntStrict(bool* ok = 0, int base = 10);
+    unsigned toUIntStrict(bool* ok = 0, int base = 10);
+    int64_t toInt64Strict(bool* ok = 0, int base = 10);
+    uint64_t toUInt64Strict(bool* ok = 0, int base = 10);
+    intptr_t toIntPtrStrict(bool* ok = 0, int base = 10);
+
+    int toInt(bool* ok = 0); // ignores trailing garbage
+    unsigned toUInt(bool* ok = 0); // ignores trailing garbage
+    int64_t toInt64(bool* ok = 0); // ignores trailing garbage
+    uint64_t toUInt64(bool* ok = 0); // ignores trailing garbage
+    intptr_t toIntPtr(bool* ok = 0); // ignores trailing garbage
+
+    double toDouble(bool* ok = 0);
+    float toFloat(bool* ok = 0);
+
+    PassRefPtr<StringImpl> lower();
+    PassRefPtr<StringImpl> upper();
+    PassRefPtr<StringImpl> secure(UChar aChar, bool last = true);
+    PassRefPtr<StringImpl> foldCase();
+
+    PassRefPtr<StringImpl> stripWhiteSpace();
+    PassRefPtr<StringImpl> simplifyWhiteSpace();
+
+    PassRefPtr<StringImpl> removeCharacters(CharacterMatchFunctionPtr);
+
+    int find(const char*, int index = 0, bool caseSensitive = true);
+    int find(UChar, int index = 0);
+    int find(CharacterMatchFunctionPtr, int index = 0);
+    int find(StringImpl*, int index, bool caseSensitive = true);
+
+    int reverseFind(UChar, int index);
+    int reverseFind(StringImpl*, int index, bool caseSensitive = true);
+    
+    bool startsWith(StringImpl* str, bool caseSensitive = true) { return reverseFind(str, 0, caseSensitive) == 0; }
+    bool endsWith(StringImpl*, bool caseSensitive = true);
+
+    PassRefPtr<StringImpl> replace(UChar, UChar);
+    PassRefPtr<StringImpl> replace(UChar, StringImpl*);
+    PassRefPtr<StringImpl> replace(StringImpl*, StringImpl*);
+    PassRefPtr<StringImpl> replace(unsigned index, unsigned len, StringImpl*);
+
+    Vector<char> ascii();
+    int wordCount(int maxWordsToCount = INT_MAX);
+
+    WTF::Unicode::Direction defaultWritingDirection();
+
+#if PLATFORM(CF)
+    CFStringRef createCFString();
+#endif
+#ifdef __OBJC__
+    operator NSString*();
+#endif
+
+private:
+    // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
+    static const unsigned s_copyCharsInlineCutOff = 20;
+
+    static PassRefPtr<StringImpl> createStrippingNullCharactersSlowCase(const UChar*, unsigned length);
+    
+    BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); }
+    bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
+    const UChar* m_data;
+    union {
+        void* m_buffer;
+        StringImpl* m_substringBuffer;
+        SharedUChar* m_sharedBuffer;
+    };
+    mutable unsigned m_hash;
+};
+
+bool equal(const StringImpl*, const StringImpl*);
+bool equal(const StringImpl*, const char*);
+inline bool equal(const char* a, StringImpl* b) { return equal(b, a); }
+
+bool equalIgnoringCase(StringImpl*, StringImpl*);
+bool equalIgnoringCase(StringImpl*, const char*);
+inline bool equalIgnoringCase(const char* a, StringImpl* b) { return equalIgnoringCase(b, a); }
+bool equalIgnoringCase(const UChar* a, const char* b, unsigned length);
+inline bool equalIgnoringCase(const char* a, const UChar* b, unsigned length) { return equalIgnoringCase(b, a, length); }
+
+bool equalIgnoringNullity(StringImpl*, StringImpl*);
+
+static inline bool isSpaceOrNewline(UChar c)
+{
+    // Use isASCIISpace() for basic Latin-1.
+    // This will include newlines, which aren't included in Unicode DirWS.
+    return c <= 0x7F ? WTF::isASCIISpace(c) : WTF::Unicode::direction(c) == WTF::Unicode::WhiteSpaceNeutral;
+}
+
+// This is a hot function because it's used when parsing HTML.
+inline PassRefPtr<StringImpl> StringImpl::createStrippingNullCharacters(const UChar* characters, unsigned length)
+{
+    ASSERT(characters);
+    ASSERT(length);
+
+    // Optimize for the case where there are no Null characters by quickly
+    // searching for nulls, and then using StringImpl::create, which will
+    // memcpy the whole buffer.  This is faster than assigning character by
+    // character during the loop. 
+
+    // Fast case.
+    int foundNull = 0;
+    for (unsigned i = 0; !foundNull && i < length; i++) {
+        int c = characters[i]; // more efficient than using UChar here (at least on Intel Mac OS)
+        foundNull |= !c;
+    }
+    if (!foundNull)
+        return StringImpl::create(characters, length);
+
+    return StringImpl::createStrippingNullCharactersSlowCase(characters, length);
+}
+
+}
+
+using WebCore::equal;
+
+namespace WTF {
+
+    // WebCore::StringHash is the default hash for StringImpl* and RefPtr<StringImpl>
+    template<typename T> struct DefaultHash;
+    template<> struct DefaultHash<WebCore::StringImpl*> {
+        typedef WebCore::StringHash Hash;
+    };
+    template<> struct DefaultHash<RefPtr<WebCore::StringImpl> > {
+        typedef WebCore::StringHash Hash;
+    };
+
+}
+
+#endif
diff --git a/wtf/text/StringImplBase.h b/wtf/text/StringImplBase.h
new file mode 100644 (file)
index 0000000..6567672
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2010 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 StringImplBase_h
+#define StringImplBase_h
+
+#include <wtf/Noncopyable.h>
+#include <wtf/unicode/Unicode.h>
+
+namespace WTF {
+
+class StringImplBase : public Noncopyable {
+public:
+    bool isStringImpl() { return (m_refCountAndFlags & s_refCountInvalidForStringImpl) != s_refCountInvalidForStringImpl; }
+    unsigned length() const { return m_length; }
+    void ref() { m_refCountAndFlags += s_refCountIncrement; }
+
+protected:
+    enum BufferOwnership {
+        BufferInternal,
+        BufferOwned,
+        BufferSubstring,
+        BufferShared,
+    };
+
+    using Noncopyable::operator new;
+    void* operator new(size_t, void* inPlace) { ASSERT(inPlace); return inPlace; }
+
+    // For SmallStringStorage, which allocates an array and uses an in-place new.
+    StringImplBase() { }
+
+    StringImplBase(unsigned length, BufferOwnership ownership)
+        : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership)
+        , m_length(length)
+    {
+        ASSERT(isStringImpl());
+    }
+
+    enum StaticStringConstructType { ConstructStaticString };
+    StringImplBase(unsigned length, StaticStringConstructType)
+        : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned)
+        , m_length(length)
+    {
+        ASSERT(isStringImpl());
+    }
+
+    // This constructor is not used when creating StringImpl objects,
+    // and sets the flags into a state marking the object as such.
+    enum NonStringImplConstructType { ConstructNonStringImpl };
+    StringImplBase(NonStringImplConstructType)
+        : m_refCountAndFlags(s_refCountIncrement | s_refCountInvalidForStringImpl)
+        , m_length(0)
+    {
+        ASSERT(!isStringImpl());
+    }
+
+    // The bottom 7 bits hold flags, the top 25 bits hold the ref count.
+    // When dereferencing StringImpls we check for the ref count AND the
+    // static bit both being zero - static strings are never deleted.
+    static const unsigned s_refCountMask = 0xFFFFFF80;
+    static const unsigned s_refCountIncrement = 0x80;
+    static const unsigned s_refCountFlagStatic = 0x40;
+    static const unsigned s_refCountFlagHasTerminatingNullCharacter = 0x20;
+    static const unsigned s_refCountFlagIsAtomic = 0x10;
+    static const unsigned s_refCountFlagShouldReportedCost = 0x8;
+    static const unsigned s_refCountFlagIsIdentifier = 0x4;
+    static const unsigned s_refCountMaskBufferOwnership = 0x3;
+    // An invalid permutation of flags (static & shouldReportedCost - static strings do not
+    // set shouldReportedCost in the constructor, and this bit is only ever cleared, not set).
+    // Used by "ConstructNonStringImpl" constructor, above.
+    static const unsigned s_refCountInvalidForStringImpl = s_refCountFlagStatic | s_refCountFlagShouldReportedCost;
+
+    unsigned m_refCountAndFlags;
+    unsigned m_length;
+};
+
+} // namespace WTF
+
+using WTF::StringImplBase;
+
+#endif
diff --git a/wtf/text/StringStatics.cpp b/wtf/text/StringStatics.cpp
new file mode 100644 (file)
index 0000000..5ee2613
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 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"
+
+#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
+#define ATOMICSTRING_HIDE_GLOBALS 1
+#endif
+
+#include "AtomicString.h"
+#include "StaticConstructors.h"
+#include "StringImpl.h"
+
+namespace WebCore {
+
+StringImpl* StringImpl::empty()
+{
+    // FIXME: This works around a bug in our port of PCRE, that a regular expression
+    // run on the empty string may still perform a read from the first element, and
+    // as such we need this to be a valid pointer. No code should ever be reading
+    // from a zero length string, so this should be able to be a non-null pointer
+    // into the zero-page.
+    // Replace this with 'reinterpret_cast<UChar*>(static_cast<intptr_t>(1))' once
+    // PCRE goes away.
+    static UChar emptyUCharData = 0;
+    DEFINE_STATIC_LOCAL(StringImpl, emptyString, (&emptyUCharData, 0, ConstructStaticString));
+    return &emptyString;
+}
+
+JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, nullAtom)
+JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, emptyAtom, "")
+JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, textAtom, "#text")
+JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, commentAtom, "#comment")
+JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, starAtom, "*")
+JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlAtom, "xml")
+JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlnsAtom, "xmlns")
+
+void AtomicString::init()
+{
+    static bool initialized;
+    if (!initialized) {
+        // On iPhone WebKit, isMainThread() tests for the Web Thread, so use pthread_main_np() instead.
+        ASSERT(pthread_main_np());
+
+        // Use placement new to initialize the globals.
+        new ((void*)&nullAtom) AtomicString;
+        new ((void*)&emptyAtom) AtomicString("");
+        new ((void*)&textAtom) AtomicString("#text");
+        new ((void*)&commentAtom) AtomicString("#comment");
+        new ((void*)&starAtom) AtomicString("*");
+        new ((void*)&xmlAtom) AtomicString("xml");
+        new ((void*)&xmlnsAtom) AtomicString("xmlns");
+
+        initialized = true;
+    }
+}
+
+}
diff --git a/wtf/text/WTFString.cpp b/wtf/text/WTFString.cpp
new file mode 100644 (file)
index 0000000..842d755
--- /dev/null
@@ -0,0 +1,913 @@
+/*
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2009 Torch Mobile, Inc.
+ *
+ * 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 "WTFString.h"
+
+#include <limits>
+#include <stdarg.h>
+#include <wtf/ASCIICType.h>
+#include <wtf/text/CString.h>
+#include <wtf/StringExtras.h>
+#include <wtf/Vector.h>
+#include <wtf/dtoa.h>
+#include <wtf/unicode/UTF8.h>
+#include <wtf/unicode/Unicode.h>
+
+using namespace WTF;
+using namespace WTF::Unicode;
+
+namespace WebCore {
+
+String::String(const UChar* str)
+{
+    if (!str)
+        return;
+        
+    int len = 0;
+    while (str[len] != UChar(0))
+        len++;
+    
+    m_impl = StringImpl::create(str, len);
+}
+
+void String::append(const String& str)
+{
+    if (str.isEmpty())
+       return;
+
+    // FIXME: This is extremely inefficient. So much so that we might want to take this
+    // out of String's API. We can make it better by optimizing the case where exactly
+    // one String is pointing at this StringImpl, but even then it's going to require a
+    // call to fastMalloc every single time.
+    if (str.m_impl) {
+        if (m_impl) {
+            UChar* data;
+            RefPtr<StringImpl> newImpl =
+                StringImpl::createUninitialized(m_impl->length() + str.length(), data);
+            memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar));
+            memcpy(data + m_impl->length(), str.characters(), str.length() * sizeof(UChar));
+            m_impl = newImpl.release();
+        } else
+            m_impl = str.m_impl;
+    }
+}
+
+void String::append(char c)
+{
+    // FIXME: This is extremely inefficient. So much so that we might want to take this
+    // out of String's API. We can make it better by optimizing the case where exactly
+    // one String is pointing at this StringImpl, but even then it's going to require a
+    // call to fastMalloc every single time.
+    if (m_impl) {
+        UChar* data;
+        RefPtr<StringImpl> newImpl =
+            StringImpl::createUninitialized(m_impl->length() + 1, data);
+        memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar));
+        data[m_impl->length()] = c;
+        m_impl = newImpl.release();
+    } else
+        m_impl = StringImpl::create(&c, 1);
+}
+
+void String::append(UChar c)
+{
+    // FIXME: This is extremely inefficient. So much so that we might want to take this
+    // out of String's API. We can make it better by optimizing the case where exactly
+    // one String is pointing at this StringImpl, but even then it's going to require a
+    // call to fastMalloc every single time.
+    if (m_impl) {
+        UChar* data;
+        RefPtr<StringImpl> newImpl =
+            StringImpl::createUninitialized(m_impl->length() + 1, data);
+        memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar));
+        data[m_impl->length()] = c;
+        m_impl = newImpl.release();
+    } else
+        m_impl = StringImpl::create(&c, 1);
+}
+
+String operator+(const String& a, const String& b)
+{
+    if (a.isEmpty())
+        return b;
+    if (b.isEmpty())
+        return a;
+    String c = a;
+    c += b;
+    return c;
+}
+
+String operator+(const String& s, const char* cs)
+{
+    return s + String(cs);
+}
+
+String operator+(const char* cs, const String& s)
+{
+    return String(cs) + s;
+}
+
+void String::insert(const String& str, unsigned pos)
+{
+    if (str.isEmpty()) {
+        if (str.isNull())
+            return;
+        if (isNull())
+            m_impl = str.impl();
+        return;
+    }
+    insert(str.characters(), str.length(), pos);
+}
+
+void String::append(const UChar* charactersToAppend, unsigned lengthToAppend)
+{
+    if (!m_impl) {
+        if (!charactersToAppend)
+            return;
+        m_impl = StringImpl::create(charactersToAppend, lengthToAppend);
+        return;
+    }
+
+    if (!lengthToAppend)
+        return;
+
+    ASSERT(charactersToAppend);
+    UChar* data;
+    RefPtr<StringImpl> newImpl =
+        StringImpl::createUninitialized(length() + lengthToAppend, data);
+    memcpy(data, characters(), length() * sizeof(UChar));
+    memcpy(data + length(), charactersToAppend, lengthToAppend * sizeof(UChar));
+    m_impl = newImpl.release();
+}
+
+void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, unsigned position)
+{
+    if (position >= length()) {
+        append(charactersToInsert, lengthToInsert);
+        return;
+    }
+
+    ASSERT(m_impl);
+
+    if (!lengthToInsert)
+        return;
+
+    ASSERT(charactersToInsert);
+    UChar* data;
+    RefPtr<StringImpl> newImpl =
+      StringImpl::createUninitialized(length() + lengthToInsert, data);
+    memcpy(data, characters(), position * sizeof(UChar));
+    memcpy(data + position, charactersToInsert, lengthToInsert * sizeof(UChar));
+    memcpy(data + position + lengthToInsert, characters() + position, (length() - position) * sizeof(UChar));
+    m_impl = newImpl.release();
+}
+
+UChar32 String::characterStartingAt(unsigned i) const
+{
+    if (!m_impl || i >= m_impl->length())
+        return 0;
+    return m_impl->characterStartingAt(i);
+}
+
+void String::truncate(unsigned position)
+{
+    if (position >= length())
+        return;
+    UChar* data;
+    RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(position, data);
+    memcpy(data, characters(), position * sizeof(UChar));
+    m_impl = newImpl.release();
+}
+
+void String::remove(unsigned position, int lengthToRemove)
+{
+    if (lengthToRemove <= 0)
+        return;
+    if (position >= length())
+        return;
+    if (static_cast<unsigned>(lengthToRemove) > length() - position)
+        lengthToRemove = length() - position;
+    UChar* data;
+    RefPtr<StringImpl> newImpl =
+        StringImpl::createUninitialized(length() - lengthToRemove, data);
+    memcpy(data, characters(), position * sizeof(UChar));
+    memcpy(data + position, characters() + position + lengthToRemove,
+        (length() - lengthToRemove - position) * sizeof(UChar));
+    m_impl = newImpl.release();
+}
+
+String String::substring(unsigned pos, unsigned len) const
+{
+    if (!m_impl) 
+        return String();
+    return m_impl->substring(pos, len);
+}
+
+String String::lower() const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->lower();
+}
+
+String String::upper() const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->upper();
+}
+
+String String::stripWhiteSpace() const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->stripWhiteSpace();
+}
+
+String String::simplifyWhiteSpace() const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->simplifyWhiteSpace();
+}
+
+String String::removeCharacters(CharacterMatchFunctionPtr findMatch) const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->removeCharacters(findMatch);
+}
+
+String String::foldCase() const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->foldCase();
+}
+
+bool String::percentage(int& result) const
+{
+    if (!m_impl || !m_impl->length())
+        return false;
+
+    if ((*m_impl)[m_impl->length() - 1] != '%')
+       return false;
+
+    result = charactersToIntStrict(m_impl->characters(), m_impl->length() - 1);
+    return true;
+}
+
+const UChar* String::charactersWithNullTermination()
+{
+    if (!m_impl)
+        return 0;
+    if (m_impl->hasTerminatingNullCharacter())
+        return m_impl->characters();
+    m_impl = StringImpl::createWithTerminatingNullCharacter(*m_impl);
+    return m_impl->characters();
+}
+
+String String::format(const char *format, ...)
+{
+#if PLATFORM(QT)
+    // Use QString::vsprintf to avoid the locale dependent formatting of vsnprintf.
+    // https://bugs.webkit.org/show_bug.cgi?id=18994
+    va_list args;
+    va_start(args, format);
+
+    QString buffer;
+    buffer.vsprintf(format, args);
+
+    va_end(args);
+
+    return buffer;
+
+#elif OS(WINCE)
+    va_list args;
+    va_start(args, format);
+
+    Vector<char, 256> buffer;
+
+    int bufferSize = 256;
+    buffer.resize(bufferSize);
+    for (;;) {
+        int written = vsnprintf(buffer.data(), bufferSize, format, args);
+        va_end(args);
+
+        if (written == 0)
+            return String("");
+        if (written > 0)
+            return StringImpl::create(buffer.data(), written);
+        
+        bufferSize <<= 1;
+        buffer.resize(bufferSize);
+        va_start(args, format);
+    }
+
+#else
+    va_list args;
+    va_start(args, format);
+
+    Vector<char, 256> buffer;
+
+    // Do the format once to get the length.
+#if COMPILER(MSVC)
+    int result = _vscprintf(format, args);
+#else
+    char ch;
+    int result = vsnprintf(&ch, 1, format, args);
+    // We need to call va_end() and then va_start() again here, as the
+    // contents of args is undefined after the call to vsnprintf
+    // according to http://man.cx/snprintf(3)
+    //
+    // Not calling va_end/va_start here happens to work on lots of
+    // systems, but fails e.g. on 64bit Linux.
+    va_end(args);
+    va_start(args, format);
+#endif
+
+    if (result == 0)
+        return String("");
+    if (result < 0)
+        return String();
+    unsigned len = result;
+    buffer.grow(len + 1);
+    
+    // Now do the formatting again, guaranteed to fit.
+    vsnprintf(buffer.data(), buffer.size(), format, args);
+
+    va_end(args);
+    
+    return StringImpl::create(buffer.data(), len);
+#endif
+}
+
+String String::number(short n)
+{
+    return String::format("%hd", n);
+}
+
+String String::number(unsigned short n)
+{
+    return String::format("%hu", n);
+}
+
+String String::number(int n)
+{
+    return String::format("%d", n);
+}
+
+String String::number(unsigned n)
+{
+    return String::format("%u", n);
+}
+
+String String::number(long n)
+{
+    return String::format("%ld", n);
+}
+
+String String::number(unsigned long n)
+{
+    return String::format("%lu", n);
+}
+
+String String::number(long long n)
+{
+#if OS(WINDOWS) && !PLATFORM(QT)
+    return String::format("%I64i", n);
+#else
+    return String::format("%lli", n);
+#endif
+}
+
+String String::number(unsigned long long n)
+{
+#if OS(WINDOWS) && !PLATFORM(QT)
+    return String::format("%I64u", n);
+#else
+    return String::format("%llu", n);
+#endif
+}
+    
+String String::number(double n)
+{
+    return String::format("%.6lg", n);
+}
+
+int String::toIntStrict(bool* ok, int base) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toIntStrict(ok, base);
+}
+
+unsigned String::toUIntStrict(bool* ok, int base) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toUIntStrict(ok, base);
+}
+
+int64_t String::toInt64Strict(bool* ok, int base) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toInt64Strict(ok, base);
+}
+
+uint64_t String::toUInt64Strict(bool* ok, int base) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toUInt64Strict(ok, base);
+}
+
+intptr_t String::toIntPtrStrict(bool* ok, int base) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toIntPtrStrict(ok, base);
+}
+
+
+int String::toInt(bool* ok) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toInt(ok);
+}
+
+unsigned String::toUInt(bool* ok) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toUInt(ok);
+}
+
+int64_t String::toInt64(bool* ok) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toInt64(ok);
+}
+
+uint64_t String::toUInt64(bool* ok) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toUInt64(ok);
+}
+
+intptr_t String::toIntPtr(bool* ok) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0;
+    }
+    return m_impl->toIntPtr(ok);
+}
+
+double String::toDouble(bool* ok) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0.0;
+    }
+    return m_impl->toDouble(ok);
+}
+
+float String::toFloat(bool* ok) const
+{
+    if (!m_impl) {
+        if (ok)
+            *ok = false;
+        return 0.0f;
+    }
+    return m_impl->toFloat(ok);
+}
+
+String String::threadsafeCopy() const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->threadsafeCopy();
+}
+
+String String::crossThreadString() const
+{
+    if (!m_impl)
+        return String();
+    return m_impl->crossThreadString();
+}
+
+void String::split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const
+{
+    result.clear();
+
+    int startPos = 0;
+    int endPos;
+    while ((endPos = find(separator, startPos)) != -1) {
+        if (allowEmptyEntries || startPos != endPos)
+            result.append(substring(startPos, endPos - startPos));
+        startPos = endPos + separator.length();
+    }
+    if (allowEmptyEntries || startPos != static_cast<int>(length()))
+        result.append(substring(startPos));
+}
+
+void String::split(const String& separator, Vector<String>& result) const
+{
+    return split(separator, false, result);
+}
+
+void String::split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const
+{
+    result.clear();
+
+    int startPos = 0;
+    int endPos;
+    while ((endPos = find(separator, startPos)) != -1) {
+        if (allowEmptyEntries || startPos != endPos)
+            result.append(substring(startPos, endPos - startPos));
+        startPos = endPos + 1;
+    }
+    if (allowEmptyEntries || startPos != static_cast<int>(length()))
+        result.append(substring(startPos));
+}
+
+void String::split(UChar separator, Vector<String>& result) const
+{
+    return split(String(&separator, 1), false, result);
+}
+
+Vector<char> String::ascii() const
+{
+    if (m_impl) 
+        return m_impl->ascii();
+    
+    const char* nullMsg = "(null impl)";
+    Vector<char, 2048> buffer;
+    for (int i = 0; nullMsg[i]; ++i)
+        buffer.append(nullMsg[i]);
+    
+    buffer.append('\0');
+    return buffer;
+}
+
+CString String::latin1() const
+{
+    // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are
+    // preserved, characters outside of this range are converted to '?'.
+
+    unsigned length = this->length();
+    const UChar* characters = this->characters();
+
+    char* characterBuffer;
+    CString result = CString::newUninitialized(length, characterBuffer);
+
+    for (unsigned i = 0; i < length; ++i) {
+        UChar ch = characters[i];
+        characterBuffer[i] = ch > 255 ? '?' : ch;
+    }
+
+    return result;
+}
+
+// Helper to write a three-byte UTF-8 code point to the buffer, caller must check room is available.
+static inline void putUTF8Triple(char*& buffer, UChar ch)
+{
+    ASSERT(ch >= 0x0800);
+    *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0);
+    *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80);
+    *buffer++ = static_cast<char>((ch & 0x3F) | 0x80);
+}
+
+CString String::utf8() const
+{
+    unsigned length = this->length();
+    const UChar* characters = this->characters();
+
+    // Allocate a buffer big enough to hold all the characters
+    // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes).
+    // Optimization ideas, if we find this function is hot:
+    //  * We could speculatively create a CStringBuffer to contain 'length' 
+    //    characters, and resize if necessary (i.e. if the buffer contains
+    //    non-ascii characters). (Alternatively, scan the buffer first for
+    //    ascii characters, so we know this will be sufficient).
+    //  * We could allocate a CStringBuffer with an appropriate size to
+    //    have a good chance of being able to write the string into the
+    //    buffer without reallocing (say, 1.5 x length).
+    Vector<char, 1024> bufferVector(length * 3);
+
+    char* buffer = bufferVector.data();
+    ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), false);
+    ASSERT(result != sourceIllegal); // Only produced from strict conversion.
+    ASSERT(result != targetExhausted); // (length * 3) should be sufficient for any conversion
+
+    // If a high surrogate is left unconverted, treat it the same was as an unpaired high surrogate
+    // would have been handled in the middle of a string with non-strict conversion - which is to say,
+    // simply encode it to UTF-8.
+    if (result == sourceExhausted) {
+        // This should be one unpaired high surrogate.
+        ASSERT((characters + 1) == (characters + length));
+        ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF));
+        // There should be room left, since one UChar hasn't been converted.
+        ASSERT((buffer + 3) <= (buffer + bufferVector.size()));
+        putUTF8Triple(buffer, *characters);
+    }
+
+    return CString(bufferVector.data(), buffer - bufferVector.data());
+}
+
+String String::fromUTF8(const char* stringStart, size_t length)
+{
+    if (!stringStart)
+        return String();
+
+    // We'll use a StringImpl as a buffer; if the source string only contains ascii this should be
+    // the right length, if there are any multi-byte sequences this buffer will be too large.
+    UChar* buffer;
+    String stringBuffer(StringImpl::createUninitialized(length, buffer));
+    UChar* bufferEnd = buffer + length;
+
+    // Try converting into the buffer.
+    const char* stringCurrent = stringStart;
+    if (convertUTF8ToUTF16(&stringCurrent, stringStart + length, &buffer, bufferEnd) != conversionOK)
+        return String();
+
+    // stringBuffer is full (the input must have been all ascii) so just return it!
+    if (buffer == bufferEnd)
+        return stringBuffer;
+
+    // stringBuffer served its purpose as a buffer, copy the contents out into a new string.
+    unsigned utf16Length = buffer - stringBuffer.characters();
+    ASSERT(utf16Length < length);
+    return String(stringBuffer.characters(), utf16Length);
+}
+
+String String::fromUTF8(const char* string)
+{
+    if (!string)
+        return String();
+    return fromUTF8(string, strlen(string));
+}
+
+String String::fromUTF8WithLatin1Fallback(const char* string, size_t size)
+{
+    String utf8 = fromUTF8(string, size);
+    if (!utf8)
+        return String(string, size);
+    return utf8;
+}
+
+// String Operations
+
+static bool isCharacterAllowedInBase(UChar c, int base)
+{
+    if (c > 0x7F)
+        return false;
+    if (isASCIIDigit(c))
+        return c - '0' < base;
+    if (isASCIIAlpha(c)) {
+        if (base > 36)
+            base = 36;
+        return (c >= 'a' && c < 'a' + base - 10)
+            || (c >= 'A' && c < 'A' + base - 10);
+    }
+    return false;
+}
+
+template <typename IntegralType>
+static inline IntegralType toIntegralType(const UChar* data, size_t length, bool* ok, int base)
+{
+    static const IntegralType integralMax = std::numeric_limits<IntegralType>::max();
+    static const bool isSigned = std::numeric_limits<IntegralType>::is_signed;
+    const IntegralType maxMultiplier = integralMax / base;
+
+    IntegralType value = 0;
+    bool isOk = false;
+    bool isNegative = false;
+
+    if (!data)
+        goto bye;
+
+    // skip leading whitespace
+    while (length && isSpaceOrNewline(*data)) {
+        length--;
+        data++;
+    }
+
+    if (isSigned && length && *data == '-') {
+        length--;
+        data++;
+        isNegative = true;
+    } else if (length && *data == '+') {
+        length--;
+        data++;
+    }
+
+    if (!length || !isCharacterAllowedInBase(*data, base))
+        goto bye;
+
+    while (length && isCharacterAllowedInBase(*data, base)) {
+        length--;
+        IntegralType digitValue;
+        UChar c = *data;
+        if (isASCIIDigit(c))
+            digitValue = c - '0';
+        else if (c >= 'a')
+            digitValue = c - 'a' + 10;
+        else
+            digitValue = c - 'A' + 10;
+
+        if (value > maxMultiplier || (value == maxMultiplier && digitValue > (integralMax % base) + isNegative))
+            goto bye;
+
+        value = base * value + digitValue;
+        data++;
+    }
+
+#if COMPILER(MSVC)
+#pragma warning(push, 0)
+#pragma warning(disable:4146)
+#endif
+
+    if (isNegative)
+        value = -value;
+
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
+    // skip trailing space
+    while (length && isSpaceOrNewline(*data)) {
+        length--;
+        data++;
+    }
+
+    if (!length)
+        isOk = true;
+bye:
+    if (ok)
+        *ok = isOk;
+    return isOk ? value : 0;
+}
+
+static unsigned lengthOfCharactersAsInteger(const UChar* data, size_t length)
+{
+    size_t i = 0;
+
+    // Allow leading spaces.
+    for (; i != length; ++i) {
+        if (!isSpaceOrNewline(data[i]))
+            break;
+    }
+    
+    // Allow sign.
+    if (i != length && (data[i] == '+' || data[i] == '-'))
+        ++i;
+    
+    // Allow digits.
+    for (; i != length; ++i) {
+        if (!isASCIIDigit(data[i]))
+            break;
+    }
+
+    return i;
+}
+
+int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base)
+{
+    return toIntegralType<int>(data, length, ok, base);
+}
+
+unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int base)
+{
+    return toIntegralType<unsigned>(data, length, ok, base);
+}
+
+int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int base)
+{
+    return toIntegralType<int64_t>(data, length, ok, base);
+}
+
+uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, int base)
+{
+    return toIntegralType<uint64_t>(data, length, ok, base);
+}
+
+intptr_t charactersToIntPtrStrict(const UChar* data, size_t length, bool* ok, int base)
+{
+    return toIntegralType<intptr_t>(data, length, ok, base);
+}
+
+int charactersToInt(const UChar* data, size_t length, bool* ok)
+{
+    return toIntegralType<int>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
+}
+
+unsigned charactersToUInt(const UChar* data, size_t length, bool* ok)
+{
+    return toIntegralType<unsigned>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
+}
+
+int64_t charactersToInt64(const UChar* data, size_t length, bool* ok)
+{
+    return toIntegralType<int64_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
+}
+
+uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok)
+{
+    return toIntegralType<uint64_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
+}
+
+intptr_t charactersToIntPtr(const UChar* data, size_t length, bool* ok)
+{
+    return toIntegralType<intptr_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10);
+}
+
+double charactersToDouble(const UChar* data, size_t length, bool* ok)
+{
+    if (!length) {
+        if (ok)
+            *ok = false;
+        return 0.0;
+    }
+
+    Vector<char, 256> bytes(length + 1);
+    for (unsigned i = 0; i < length; ++i)
+        bytes[i] = data[i] < 0x7F ? data[i] : '?';
+    bytes[length] = '\0';
+    char* end;
+    double val = WTF::strtod(bytes.data(), &end);
+    if (ok)
+        *ok = (end == 0 || *end == '\0');
+    return val;
+}
+
+float charactersToFloat(const UChar* data, size_t length, bool* ok)
+{
+    // FIXME: This will return ok even when the string fits into a double but not a float.
+    return static_cast<float>(charactersToDouble(data, length, ok));
+}
+
+} // namespace WebCore
+
+#ifndef NDEBUG
+// For use in the debugger - leaks memory
+WebCore::String* string(const char*);
+
+WebCore::String* string(const char* s)
+{
+    return new WebCore::String(s);
+}
+#endif
diff --git a/wtf/text/WTFString.h b/wtf/text/WTFString.h
new file mode 100644 (file)
index 0000000..493e793
--- /dev/null
@@ -0,0 +1,430 @@
+/*
+ * (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU 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 WTFString_h
+#define WTFString_h
+
+// This file would be called String.h, but that conflicts with <string.h>
+// on systems without case-sensitive file systems.
+
+#include "StringImpl.h"
+
+#ifdef __OBJC__
+#include <objc/objc.h>
+#endif
+
+#if PLATFORM(CF)
+typedef const struct __CFString * CFStringRef;
+#endif
+
+#if PLATFORM(QT)
+QT_BEGIN_NAMESPACE
+class QString;
+QT_END_NAMESPACE
+#include <QDataStream>
+#endif
+
+#if PLATFORM(WX)
+class wxString;
+#endif
+
+#if PLATFORM(HAIKU)
+class BString;
+#endif
+
+namespace WTF {
+class CString;
+}
+using WTF::CString;
+
+// FIXME: This is a temporary layering violation while we move string code to WTF.
+// Landing the file moves in one patch, will follow on with patches to change the namespaces.
+namespace WebCore {
+
+class SharedBuffer;
+struct StringHash;
+
+// Declarations of string operations
+
+bool charactersAreAllASCII(const UChar*, size_t);
+int charactersToIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10);
+unsigned charactersToUIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10);
+int64_t charactersToInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10);
+uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10);
+intptr_t charactersToIntPtrStrict(const UChar*, size_t, bool* ok = 0, int base = 10);
+
+int charactersToInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
+unsigned charactersToUInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
+int64_t charactersToInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
+uint64_t charactersToUInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
+intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage
+
+double charactersToDouble(const UChar*, size_t, bool* ok = 0);
+float charactersToFloat(const UChar*, size_t, bool* ok = 0);
+
+int find(const UChar*, size_t, UChar, int startPosition = 0);
+int reverseFind(const UChar*, size_t, UChar, int startPosition = -1);
+
+class String {
+public:
+    String() { } // gives null string, distinguishable from an empty string
+    String(const UChar* str, unsigned len)
+    {
+        if (!str)
+            return;
+        m_impl = StringImpl::create(str, len);
+    }
+    String(const char* str)
+    {
+        if (!str)
+            return;
+        m_impl = StringImpl::create(str);
+    }
+    String(const char* str, unsigned length)
+    {
+        if (!str)
+            return;
+        m_impl = StringImpl::create(str, length);
+    }
+    String(const UChar*); // Specifically for null terminated UTF-16
+    String(StringImpl* i) : m_impl(i) { }
+    String(PassRefPtr<StringImpl> i) : m_impl(i) { }
+    String(RefPtr<StringImpl> i) : m_impl(i) { }
+
+    void swap(String& o) { m_impl.swap(o.m_impl); }
+
+    // Hash table deleted values, which are only constructed and never copied or destroyed.
+    String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { }
+    bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); }
+
+    static String adopt(StringBuffer& buffer) { return StringImpl::adopt(buffer); }
+    static String adopt(Vector<UChar>& vector) { return StringImpl::adopt(vector); }
+
+    ALWAYS_INLINE unsigned length() const
+    {
+        if (!m_impl)
+            return 0;
+        return m_impl->length();
+    }
+
+    const UChar* characters() const
+    {
+        if (!m_impl)
+            return 0;
+        return m_impl->characters();
+    }
+
+    const UChar* charactersWithNullTermination();
+    
+    UChar operator[](unsigned i) const // if i >= length(), returns 0
+    {
+        if (!m_impl || i >= m_impl->length())
+            return 0;
+        return m_impl->characters()[i];
+    }
+    UChar32 characterStartingAt(unsigned) const; // Ditto.
+    
+    bool contains(UChar c) const { return find(c) != -1; }
+    bool contains(const char* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != -1; }
+    bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != -1; }
+
+    int find(UChar c, int start = 0) const
+        { return m_impl ? m_impl->find(c, start) : -1; }
+    int find(CharacterMatchFunctionPtr matchFunction, int start = 0) const
+        { return m_impl ? m_impl->find(matchFunction, start) : -1; }
+    int find(const char* str, int start = 0, bool caseSensitive = true) const
+        { return m_impl ? m_impl->find(str, start, caseSensitive) : -1; }
+    int find(const String& str, int start = 0, bool caseSensitive = true) const
+        { return m_impl ? m_impl->find(str.impl(), start, caseSensitive) : -1; }
+
+    int reverseFind(UChar c, int start = -1) const
+        { return m_impl ? m_impl->reverseFind(c, start) : -1; }
+    int reverseFind(const String& str, int start = -1, bool caseSensitive = true) const
+        { return m_impl ? m_impl->reverseFind(str.impl(), start, caseSensitive) : -1; }
+    
+    bool startsWith(const String& s, bool caseSensitive = true) const
+        { return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); }
+    bool endsWith(const String& s, bool caseSensitive = true) const
+        { return m_impl ? m_impl->endsWith(s.impl(), caseSensitive) : s.isEmpty(); }
+
+    void append(const String&);
+    void append(char);
+    void append(UChar);
+    void append(const UChar*, unsigned length);
+    void insert(const String&, unsigned pos);
+    void insert(const UChar*, unsigned length, unsigned pos);
+
+    String& replace(UChar a, UChar b) { if (m_impl) m_impl = m_impl->replace(a, b); return *this; }
+    String& replace(UChar a, const String& b) { if (m_impl) m_impl = m_impl->replace(a, b.impl()); return *this; }
+    String& replace(const String& a, const String& b) { if (m_impl) m_impl = m_impl->replace(a.impl(), b.impl()); return *this; }
+    String& replace(unsigned index, unsigned len, const String& b) { if (m_impl) m_impl = m_impl->replace(index, len, b.impl()); return *this; }
+
+    void makeLower() { if (m_impl) m_impl = m_impl->lower(); }
+    void makeUpper() { if (m_impl) m_impl = m_impl->upper(); }
+    void makeSecure(UChar aChar, bool last = true) { if (m_impl) m_impl = m_impl->secure(aChar, last); }
+
+    void truncate(unsigned len);
+    void remove(unsigned pos, int len = 1);
+
+    String substring(unsigned pos, unsigned len = UINT_MAX) const;
+    String left(unsigned len) const { return substring(0, len); }
+    String right(unsigned len) const { return substring(length() - len, len); }
+
+    // Returns a lowercase/uppercase version of the string
+    String lower() const;
+    String upper() const;
+
+    String stripWhiteSpace() const;
+    String simplifyWhiteSpace() const;
+
+    String removeCharacters(CharacterMatchFunctionPtr) const;
+
+    // Return the string with case folded for case insensitive comparison.
+    String foldCase() const;
+
+    static String number(short);
+    static String number(unsigned short);
+    static String number(int);
+    static String number(unsigned);
+    static String number(long);
+    static String number(unsigned long);
+    static String number(long long);
+    static String number(unsigned long long);
+    static String number(double);
+    
+    static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
+
+    // Returns an uninitialized string. The characters needs to be written
+    // into the buffer returned in data before the returned string is used.
+    // Failure to do this will have unpredictable results.
+    static String createUninitialized(unsigned length, UChar*& data) { return StringImpl::createUninitialized(length, data); }
+
+    void split(const String& separator, Vector<String>& result) const;
+    void split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const;
+    void split(UChar separator, Vector<String>& result) const;
+    void split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const;
+
+    int toIntStrict(bool* ok = 0, int base = 10) const;
+    unsigned toUIntStrict(bool* ok = 0, int base = 10) const;
+    int64_t toInt64Strict(bool* ok = 0, int base = 10) const;
+    uint64_t toUInt64Strict(bool* ok = 0, int base = 10) const;
+    intptr_t toIntPtrStrict(bool* ok = 0, int base = 10) const;
+
+    int toInt(bool* ok = 0) const;
+    unsigned toUInt(bool* ok = 0) const;
+    int64_t toInt64(bool* ok = 0) const;
+    uint64_t toUInt64(bool* ok = 0) const;
+    intptr_t toIntPtr(bool* ok = 0) const;
+    double toDouble(bool* ok = 0) const;
+    float toFloat(bool* ok = 0) const;
+
+    bool percentage(int& percentage) const;
+
+    // Returns a StringImpl suitable for use on another thread.
+    String crossThreadString() const;
+    // Makes a deep copy. Helpful only if you need to use a String on another thread
+    // (use crossThreadString if the method call doesn't need to be threadsafe).
+    // Since the underlying StringImpl objects are immutable, there's no other reason
+    // to ever prefer copy() over plain old assignment.
+    String threadsafeCopy() const;
+
+    bool isNull() const { return !m_impl; }
+    ALWAYS_INLINE bool isEmpty() const { return !m_impl || !m_impl->length(); }
+
+    StringImpl* impl() const { return m_impl.get(); }
+
+#if PLATFORM(CF)
+    String(CFStringRef);
+    CFStringRef createCFString() const;
+#endif
+
+#ifdef __OBJC__
+    String(NSString*);
+    
+    // This conversion maps NULL to "", which loses the meaning of NULL, but we 
+    // need this mapping because AppKit crashes when passed nil NSStrings.
+    operator NSString*() const { if (!m_impl) return @""; return *m_impl; }
+#endif
+
+#if PLATFORM(QT)
+    String(const QString&);
+    String(const QStringRef&);
+    operator QString() const;
+#endif
+
+#if PLATFORM(WX)
+    String(const wxString&);
+    operator wxString() const;
+#endif
+
+#if PLATFORM(HAIKU)
+    String(const BString&);
+    operator BString() const;
+#endif
+
+    Vector<char> ascii() const;
+
+    CString latin1() const;
+    CString utf8() const;
+
+    static String fromUTF8(const char*, size_t);
+    static String fromUTF8(const char*);
+
+    // Tries to convert the passed in string to UTF-8, but will fall back to Latin-1 if the string is not valid UTF-8.
+    static String fromUTF8WithLatin1Fallback(const char*, size_t);
+    
+    // Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3.
+    WTF::Unicode::Direction defaultWritingDirection() const { return m_impl ? m_impl->defaultWritingDirection() : WTF::Unicode::LeftToRight; }
+
+    bool containsOnlyASCII() const { return charactersAreAllASCII(characters(), length()); }
+
+private:
+    RefPtr<StringImpl> m_impl;
+};
+
+#if PLATFORM(QT)
+QDataStream& operator<<(QDataStream& stream, const String& str);
+QDataStream& operator>>(QDataStream& stream, String& str);
+#endif
+
+String operator+(const String&, const String&);
+String operator+(const String&, const char*);
+String operator+(const char*, const String&);
+
+inline String& operator+=(String& a, const String& b) { a.append(b); return a; }
+
+inline bool operator==(const String& a, const String& b) { return equal(a.impl(), b.impl()); }
+inline bool operator==(const String& a, const char* b) { return equal(a.impl(), b); }
+inline bool operator==(const char* a, const String& b) { return equal(a, b.impl()); }
+
+inline bool operator!=(const String& a, const String& b) { return !equal(a.impl(), b.impl()); }
+inline bool operator!=(const String& a, const char* b) { return !equal(a.impl(), b); }
+inline bool operator!=(const char* a, const String& b) { return !equal(a, b.impl()); }
+
+inline bool equalIgnoringCase(const String& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); }
+inline bool equalIgnoringCase(const String& a, const char* b) { return equalIgnoringCase(a.impl(), b); }
+inline bool equalIgnoringCase(const char* a, const String& b) { return equalIgnoringCase(a, b.impl()); }
+
+inline bool equalPossiblyIgnoringCase(const String& a, const String& b, bool ignoreCase) 
+{
+    return ignoreCase ? equalIgnoringCase(a, b) : (a == b);
+}
+
+inline bool equalIgnoringNullity(const String& a, const String& b) { return equalIgnoringNullity(a.impl(), b.impl()); }
+
+inline bool operator!(const String& str) { return str.isNull(); }
+
+inline void swap(String& a, String& b) { a.swap(b); }
+
+// Definitions of string operations
+
+#ifdef __OBJC__
+// This is for situations in WebKit where the long standing behavior has been
+// "nil if empty", so we try to maintain longstanding behavior for the sake of
+// entrenched clients
+inline NSString* nsStringNilIfEmpty(const String& str) {  return str.isEmpty() ? nil : (NSString*)str; }
+#endif
+
+inline bool charactersAreAllASCII(const UChar* characters, size_t length)
+{
+    UChar ored = 0;
+    for (size_t i = 0; i < length; ++i)
+        ored |= characters[i];
+    return !(ored & 0xFF80);
+}
+
+inline int find(const UChar* characters, size_t length, UChar character, int startPosition)
+{
+    if (startPosition >= static_cast<int>(length))
+        return -1;
+    for (size_t i = startPosition; i < length; ++i) {
+        if (characters[i] == character)
+            return static_cast<int>(i);
+    }
+    return -1;
+}
+
+inline int find(const UChar* characters, size_t length, CharacterMatchFunctionPtr matchFunction, int startPosition)
+{
+    if (startPosition >= static_cast<int>(length))
+        return -1;
+    for (size_t i = startPosition; i < length; ++i) {
+        if (matchFunction(characters[i]))
+            return static_cast<int>(i);
+    }
+    return -1;
+}
+
+inline int reverseFind(const UChar* characters, size_t length, UChar character, int startPosition)
+{
+    if (startPosition >= static_cast<int>(length) || !length)
+        return -1;
+    if (startPosition < 0)
+        startPosition += static_cast<int>(length);
+    while (true) {
+        if (characters[startPosition] == character)
+            return startPosition;
+        if (!startPosition)
+            return -1;
+        startPosition--;
+    }
+    ASSERT_NOT_REACHED();
+    return -1;
+}
+
+inline void append(Vector<UChar>& vector, const String& string)
+{
+    vector.append(string.characters(), string.length());
+}
+
+inline void appendNumber(Vector<UChar>& vector, unsigned char number)
+{
+    int numberLength = number > 99 ? 3 : (number > 9 ? 2 : 1);
+    size_t vectorSize = vector.size();
+    vector.grow(vectorSize + numberLength);
+
+    switch (numberLength) {
+    case 3:
+        vector[vectorSize + 2] = number % 10 + '0';
+        number /= 10;
+
+    case 2:
+        vector[vectorSize + 1] = number % 10 + '0';
+        number /= 10;
+
+    case 1:
+        vector[vectorSize] = number % 10 + '0';
+    }
+}
+
+} // namespace WebCore
+
+namespace WTF {
+
+    // StringHash is the default hash for String
+    template<typename T> struct DefaultHash;
+    template<> struct DefaultHash<WebCore::String> {
+        typedef WebCore::StringHash Hash;
+    };
+
+}
+
+#endif
index 51e8a063f2323ab1044abff70a4eae8834402fcc..fe6a8096ce6adff570a1f54c6bc3096141f85b3c 100644 (file)
@@ -29,8 +29,8 @@
 #ifndef WTF_Collator_h
 #define WTF_Collator_h
 
 #ifndef WTF_Collator_h
 #define WTF_Collator_h
 
-#include <memory>
 #include <wtf/Noncopyable.h>
 #include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
 #include <wtf/unicode/Unicode.h>
 
 #if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION
 #include <wtf/unicode/Unicode.h>
 
 #if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION
@@ -47,7 +47,7 @@ namespace WTF {
         ~Collator();
         void setOrderLowerFirst(bool);
 
         ~Collator();
         void setOrderLowerFirst(bool);
 
-        static std::auto_ptr<Collator> userDefault();
+        static PassOwnPtr<Collator> userDefault();
 
         Result collate(const ::UChar*, size_t, const ::UChar*, size_t) const;
 
 
         Result collate(const ::UChar*, size_t, const ::UChar*, size_t) const;
 
index eddbe534ffaa554be285d5be8f48aea3cb1f1e70..4e05432243671f34bb00ffd0c81b3d65cd6f939e 100644 (file)
@@ -45,9 +45,9 @@ void Collator::setOrderLowerFirst(bool)
 {
 }
 
 {
 }
 
-std::auto_ptr<Collator> Collator::userDefault()
+PassOwnPtr<Collator> Collator::userDefault()
 {
 {
-    return std::auto_ptr<Collator>(new Collator(0));
+    return new Collator(0);
 }
 
 // A default implementation for platforms that lack Unicode-aware collation.
 }
 
 // A default implementation for platforms that lack Unicode-aware collation.
index d72e707abcd46c9494480835b8d722aed4c84424..46b00ea89c236af35eee8939ff8095a17f23d84e 100644 (file)
@@ -26,7 +26,7 @@
 #define UnicodeGLib_h
 
 #include "UnicodeMacrosFromICU.h"
 #define UnicodeGLib_h
 
 #include "UnicodeMacrosFromICU.h"
-#include <wtf/gtk/GOwnPtr.h>
+#include "GOwnPtr.h"
 
 #include <glib.h>
 #include <pango/pango.h>
 
 #include <glib.h>
 #include <pango/pango.h>
index a1753a4c096f0502aed3cc75c4c2290dffed6fc0..ecab5bdc37642fbf89b8a65643f15f9b0f351be7 100644 (file)
@@ -57,7 +57,7 @@ Collator::Collator(const char* locale)
 {
 }
 
 {
 }
 
-std::auto_ptr<Collator> Collator::userDefault()
+PassOwnPtr<Collator> Collator::userDefault()
 {
 #if OS(DARWIN) && PLATFORM(CF)
     // Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work.
 {
 #if OS(DARWIN) && PLATFORM(CF)
     // Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work.
@@ -71,11 +71,11 @@ std::auto_ptr<Collator> Collator::userDefault()
     char buf[256];
     if (collationOrder) {
         CFStringGetCString(collationOrder, buf, sizeof(buf), kCFStringEncodingASCII);
     char buf[256];
     if (collationOrder) {
         CFStringGetCString(collationOrder, buf, sizeof(buf), kCFStringEncodingASCII);
-        return std::auto_ptr<Collator>(new Collator(buf));
+        return new Collator(buf);
     } else
     } else
-        return std::auto_ptr<Collator>(new Collator(""));
+        return new Collator("");
 #else
 #else
-    return std::auto_ptr<Collator>(new Collator(0));
+    return new Collator(0);
 #endif
 }
 
 #endif
 }
 
index cfd482d995363cef83452ab220164ef6f47e0e2e..97c42b7bb810b9146a32963a2f4211d271cc0112 100644 (file)
@@ -56,7 +56,7 @@ namespace QUnicodeTables {
 QT_END_NAMESPACE
 
 // ugly hack to make UChar compatible with JSChar in API/JSStringRef.h
 QT_END_NAMESPACE
 
 // ugly hack to make UChar compatible with JSChar in API/JSStringRef.h
-#if defined(Q_OS_WIN) || COMPILER(WINSCW)
+#if defined(Q_OS_WIN) || COMPILER(WINSCW) || (COMPILER(RVCT) && OS(SYMBIAN))
 typedef wchar_t UChar;
 #else
 typedef uint16_t UChar;
 typedef wchar_t UChar;
 #else
 typedef uint16_t UChar;
diff --git a/wtf/url/src/URLComponent.h b/wtf/url/src/URLComponent.h
new file mode 100644 (file)
index 0000000..ca7e6f3
--- /dev/null
@@ -0,0 +1,71 @@
+// Copyright 2010, 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 URLComponent_h
+#define URLComponent_h
+
+namespace WTF {
+
+// Represents a substring for URL parsing.
+class URLComponent {
+public:
+    URLComponent() : m_begin(0), m_length(-1) { }
+    URLComponent(int begin, int length) : m_begin(begin), m_length(length) { }
+
+    // Returns true if this component is valid, meaning the length is given. Even
+    // valid components may be empty to record the fact that they exist.
+    bool isValid() const { return m_length != -1; }
+
+    // Returns true if the given component is specified on false, the component
+    // is either empty or invalid.
+    bool isNonempty() const { return m_length > 0; }
+
+    void reset()
+    {
+        m_begin = 0;
+        m_length = -1;
+    }
+
+    bool operator==(const URLComponent& other) const { return m_begin == other.m_begin && m_length == other.m_length; }
+
+    int begin() const { return m_begin; }
+    void setBegin(int begin) { m_begin = begin; }
+
+    int length() const { return m_length; }
+    void setLength(int length) { m_length = length; }
+
+    int end() const { return m_begin + m_length; }
+
+private:
+    int m_begin; // Byte offset in the string of this component.
+    int m_length; // Will be -1 if the component is unspecified.
+};
+
+} // namespace WTF
+
+#endif // URLComponent_h
diff --git a/wtf/url/src/URLSegments.cpp b/wtf/url/src/URLSegments.cpp
new file mode 100644 (file)
index 0000000..bb9542f
--- /dev/null
@@ -0,0 +1,110 @@
+/* Based on nsURLParsers.cc from Mozilla
+ * -------------------------------------
+ * Copyright (C) 1998 Netscape Communications Corporation.
+ *
+ * Other contributors:
+ *   Darin Fisher (original author)
+ *
+ * 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 "URLSegments.h"
+
+namespace WTF {
+
+int URLSegments::length() const
+{
+    if (fragment.isValid())
+        return fragment.end();
+    return charactersBefore(Fragment, false);
+}
+
+int URLSegments::charactersBefore(ComponentType type, bool includeDelimiter) const
+{
+    if (type == Scheme)
+        return scheme.begin();
+
+    int current = 0;
+    if (scheme.isValid())
+        current = scheme.end() + 1; // Advance over the ':' at the end of the scheme.
+
+    if (username.isValid()) {
+        if (type <= Username)
+            return username.begin();
+        current = username.end() + 1; // Advance over the '@' or ':' at the end.
+    }
+
+    if (password.isValid()) {
+        if (type <= Password)
+            return password.begin();
+        current = password.end() + 1; // Advance over the '@' at the end.
+    }
+
+    if (host.isValid()) {
+        if (type <= Host)
+            return host.begin();
+        current = host.end();
+    }
+
+    if (port.isValid()) {
+        if (type < Port || (type == Port && includeDelimiter))
+            return port.begin() - 1; // Back over delimiter.
+        if (type == Port)
+            return port.begin(); // Don't want delimiter counted.
+        current = port.end();
+    }
+
+    if (path.isValid()) {
+        if (type <= Path)
+            return path.begin();
+        current = path.end();
+    }
+
+    if (query.isValid()) {
+        if (type < Query || (type == Query && includeDelimiter))
+            return query.begin() - 1; // Back over delimiter.
+        if (type == Query)
+            return query.begin(); // Don't want delimiter counted.
+        current = query.end();
+    }
+
+    if (fragment.isValid()) {
+        if (type == Fragment && !includeDelimiter)
+            return fragment.begin(); // Back over delimiter.
+
+        // When there is a fragment and we get here, the component we wanted was before
+        // this and not found, so we always know the beginning of the fragment is right.
+        return fragment.begin() - 1; // Don't want delimiter counted.
+    }
+
+    return current;
+}
+
+} // namespace WTF
diff --git a/wtf/url/src/URLSegments.h b/wtf/url/src/URLSegments.h
new file mode 100644 (file)
index 0000000..436c7fe
--- /dev/null
@@ -0,0 +1,105 @@
+// Copyright 2007, 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 URLSegments_h
+#define URLSegments_h
+
+#include "URLComponent.h"
+
+namespace WTF {
+
+// A structure that holds the identified parts of an input URL. This structure
+// does NOT store the URL itself. The caller will have to store the URL text
+// and its corresponding Parsed structure separately.
+class URLSegments {
+public:
+    // Identifies different components.
+    enum ComponentType {
+        Scheme,
+        Username,
+        Password,
+        Host,
+        Port,
+        Path,
+        Query,
+        Fragment,
+    };
+
+    URLSegments() { }
+
+    // Returns the length of the URL (the end of the last component).
+    //
+    // Note that for some invalid, non-canonical URLs, this may not be the length
+    // of the string. For example "http://": the parsed structure will only
+    // contain an entry for the four-character scheme, and it doesn't know about
+    // the "://". For all other last-components, it will return the real length.
+    int length() const;
+
+    // Returns the number of characters before the given component if it exists,
+    // or where the component would be if it did exist. This will return the
+    // string length if the component would be appended to the end.
+    //
+    // Note that this can get a little funny for the port, query, and fragment
+    // components which have a delimiter that is not counted as part of the
+    // component. The |includeDelimiter| flag controls if you want this counted
+    // as part of the component or not when the component exists.
+    //
+    // This example shows the difference between the two flags for two of these
+    // delimited components that is present (the port and query) and one that
+    // isn't (the reference). The components that this flag affects are marked
+    // with a *.
+    //                 0         1         2
+    //                 012345678901234567890
+    // Example input:  http://foo:80/?query
+    //              include_delim=true,  ...=false  ("<-" indicates different)
+    //      Scheme: 0                    0
+    //    Username: 5                    5
+    //    Password: 5                    5
+    //        Host: 7                    7
+    //       *Port: 10                   11 <-
+    //        Path: 13                   13
+    //      *Query: 14                   15 <-
+    //        *Fragment: 20                   20
+    //
+    int charactersBefore(ComponentType, bool includeDelimiter) const;
+
+    // Each component excludes the related delimiters and has a length of -1
+    // if that component is absent but 0 if the component exists but is empty.
+    URLComponent scheme;
+    URLComponent username;
+    URLComponent password;
+    URLComponent host;
+    URLComponent port;
+    URLComponent path;
+    URLComponent query;
+    URLComponent fragment;
+};
+
+} // namespace WTF
+
+#endif // URLSegments_h
diff --git a/wtf/url/wtfurl.gyp b/wtf/url/wtfurl.gyp
new file mode 100644 (file)
index 0000000..f254ae4
--- /dev/null
@@ -0,0 +1,58 @@
+# 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.
+
+{
+  'variables': {
+    'chromium_code': 1,
+  },
+  'targets': [
+    {
+      'target_name': 'wtfurl',
+      'type': '<(library)',
+      'msvs_guid': 'EF5E94AB-B646-4E5B-A058-52EF07B8351C',
+      'dependencies': [
+      ],
+      'sources': [
+        'src/URLComponent.h',
+        'src/URLSegments.cpp',
+        'src/URLSegments.h',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          'src',
+        ],
+      },
+    },
+  ],
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2:
index ee70b59b670aa1b4b3fe930161fc299f2acd7f97..ee3a273776b0df3fe69fd631cc1827bb0e797456 100644 (file)
@@ -77,6 +77,8 @@ void initializeMainThreadPlatform()
     threadingWindowHandle = CreateWindow(kThreadingWindowClassName, 0, 0,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, hWndParent, 0, 0, 0);
     threadingFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.MainThreadFired");
     threadingWindowHandle = CreateWindow(kThreadingWindowClassName, 0, 0,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, hWndParent, 0, 0, 0);
     threadingFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.MainThreadFired");
+
+    initializeCurrentThreadInternal("Main Thread");
 }
 
 void scheduleDispatchFunctionsOnMainThread()
 }
 
 void scheduleDispatchFunctionsOnMainThread()
diff --git a/wtf/win/OwnPtrWin.cpp b/wtf/win/OwnPtrWin.cpp
new file mode 100644 (file)
index 0000000..67a32ff
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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
+ * 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 COMPUTER, 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 COMPUTER, 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 "OwnPtr.h"
+
+#include <windows.h>
+
+namespace WTF {
+
+void deleteOwnedPtr(HBITMAP ptr)
+{
+    if (ptr)
+        DeleteObject(ptr);
+}
+
+void deleteOwnedPtr(HBRUSH ptr)
+{
+    if (ptr)
+        DeleteObject(ptr);
+}
+
+void deleteOwnedPtr(HDC ptr)
+{
+    if (ptr)
+        DeleteDC(ptr);
+}
+
+void deleteOwnedPtr(HFONT ptr)
+{
+    if (ptr)
+        DeleteObject(ptr);
+}
+
+void deleteOwnedPtr(HPALETTE ptr)
+{
+    if (ptr)
+        DeleteObject(ptr);
+}
+
+void deleteOwnedPtr(HPEN ptr)
+{
+    if (ptr)
+        DeleteObject(ptr);
+}
+
+void deleteOwnedPtr(HRGN ptr)
+{
+    if (ptr)
+        DeleteObject(ptr);
+}
+
+}
index bcd5f0591daa58eda557682996d468c9d896b244..e1d15c96f6eb447904b52e95d0fd4dc07d2af598 100644 (file)
 #include "config.h"
 #include "MainThread.h"
 
 #include "config.h"
 #include "MainThread.h"
 
+#include <wx/defs.h>
+#include <wx/app.h>
+#include <wx/event.h>
+
+const wxEventType wxEVT_CALL_AFTER = wxNewEventType();
+
+class wxCallAfter : public wxEvtHandler
+{
+public:
+    wxCallAfter() 
+        : wxEvtHandler()
+        {
+            wxTheApp->Connect(-1, -1, wxEVT_CALL_AFTER, wxCommandEventHandler(wxCallAfter::OnCallback));
+            wxCommandEvent event(wxEVT_CALL_AFTER);
+            wxPostEvent(wxTheApp, event);
+        }
+        
+    void OnCallback(wxCommandEvent& event)
+    {
+        WTF::dispatchFunctionsFromMainThread();
+    }
+};
+
 namespace WTF {
 
 void initializeMainThreadPlatform()
 namespace WTF {
 
 void initializeMainThreadPlatform()
@@ -37,6 +60,7 @@ void initializeMainThreadPlatform()
 
 void scheduleDispatchFunctionsOnMainThread()
 {
 
 void scheduleDispatchFunctionsOnMainThread()
 {
+    wxCallAfter();
 }
 
 } // namespace WTF
 }
 
 } // namespace WTF
index 9cd3d123c1cf8b6294a4bd0859aa388a149eaff3..9fbe213c40d59e2039b8a73c3cd59bbfe8ff68cc 100644 (file)
@@ -36,6 +36,8 @@ using namespace WTF;
 
 namespace JSC { namespace Yarr {
 
 
 namespace JSC { namespace Yarr {
 
+#include "RegExpJitTables.h"
+
 class CharacterClassConstructor {
 public:
     CharacterClassConstructor(bool isCaseInsensitive = false)
 class CharacterClassConstructor {
 public:
     CharacterClassConstructor(bool isCaseInsensitive = false)
@@ -141,7 +143,7 @@ public:
 
     CharacterClass* charClass()
     {
 
     CharacterClass* charClass()
     {
-        CharacterClass* characterClass = new CharacterClass();
+        CharacterClass* characterClass = new CharacterClass(0);
 
         characterClass->m_matches.append(m_matches);
         characterClass->m_ranges.append(m_ranges);
 
         characterClass->m_matches.append(m_matches);
         characterClass->m_ranges.append(m_ranges);
@@ -233,105 +235,6 @@ private:
     Vector<CharacterRange> m_rangesUnicode;
 };
 
     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)
 class RegexPatternConstructor {
 public:
     RegexPatternConstructor(RegexPattern& pattern)
@@ -469,6 +372,7 @@ public:
     void atomBackReference(unsigned subpatternId)
     {
         ASSERT(subpatternId);
     void atomBackReference(unsigned subpatternId)
     {
         ASSERT(subpatternId);
+        m_pattern.m_shouldFallBack = true;
         m_pattern.m_maxBackReference = std::max(m_pattern.m_maxBackReference, subpatternId);
 
         if (subpatternId > m_pattern.m_numSubpatterns) {
         m_pattern.m_maxBackReference = std::max(m_pattern.m_maxBackReference, subpatternId);
 
         if (subpatternId > m_pattern.m_numSubpatterns) {
@@ -544,6 +448,9 @@ public:
             return;
         }
 
             return;
         }
 
+        if (max > 1 && term.type == PatternTerm::TypeParenthesesSubpattern)
+            m_pattern.m_shouldFallBack = true;
+
         if (min == 0)
             term.quantify(max, greedy   ? QuantifierGreedy : QuantifierNonGreedy);
         else if (min == max)
         if (min == 0)
             term.quantify(max, greedy   ? QuantifierGreedy : QuantifierNonGreedy);
         else if (min == max)
index 3ed2be9e4a441de4a37f8c87cf6334aebced4313..9d2443a5918b8a331a943585a6e14f2fd7dbca02 100644 (file)
 #ifndef RegexCompiler_h
 #define RegexCompiler_h
 
 #ifndef RegexCompiler_h
 #define RegexCompiler_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(YARR)
 
 #if ENABLE(YARR)
 
-#include <wtf/unicode/Unicode.h>
 #include "RegexParser.h"
 #include "RegexPattern.h"
 #include "RegexParser.h"
 #include "RegexPattern.h"
+#include <wtf/unicode/Unicode.h>
 
 namespace JSC { namespace Yarr {
 
 
 namespace JSC { namespace Yarr {
 
index d0880866a35653b20fab2bf881acbef8385c1c99..647b20a8656198eb63742aac1cc86fb1579fda69 100644 (file)
@@ -280,20 +280,6 @@ public:
         return false;
     }
 
         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 checkCharacter(int testChar, int inputPosition)
     {
         return testChar == input.readChecked(inputPosition);
@@ -305,23 +291,6 @@ public:
         return (loChar == ch) || (hiChar == ch);
     }
 
         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));
     bool checkCharacterClass(CharacterClass* characterClass, bool invert, int inputPosition)
     {
         bool match = testCharacterClass(characterClass, input.readChecked(inputPosition));
@@ -1585,7 +1554,7 @@ public:
                 }
 
                 case PatternTerm::TypeParentheticalAssertion: {
                 }
 
                 case PatternTerm::TypeParentheticalAssertion: {
-                    unsigned alternativeFrameLocation = term.inputPosition + RegexStackSpaceForBackTrackInfoParentheticalAssertion;
+                    unsigned alternativeFrameLocation = term.frameLocation + RegexStackSpaceForBackTrackInfoParentheticalAssertion;
 
                     atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invertOrCapture, term.frameLocation, alternativeFrameLocation);
                     emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0);
 
                     atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invertOrCapture, term.frameLocation, alternativeFrameLocation);
                     emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0);
index 48c9a5ef855c4006458e40ac5950ece79097eece..e3c31222819b87104cfab8969ca0e9e09709ca7f 100644 (file)
 #ifndef RegexInterpreter_h
 #define RegexInterpreter_h
 
 #ifndef RegexInterpreter_h
 #define RegexInterpreter_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(YARR)
 
 #if ENABLE(YARR)
 
-#include <wtf/unicode/Unicode.h>
 #include "RegexParser.h"
 #include "RegexPattern.h"
 #include "RegexParser.h"
 #include "RegexPattern.h"
+#include <wtf/unicode/Unicode.h>
 
 namespace JSC { namespace Yarr {
 
 
 namespace JSC { namespace Yarr {
 
index fcb8d86ae93f92c78b5347ad7631a888b6e4a672..7707cbabe040790e411165036785667b915eedc5 100644 (file)
@@ -40,7 +40,6 @@ using namespace WTF;
 
 namespace JSC { namespace Yarr {
 
 
 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);
 
 class RegexGenerator : private MacroAssembler {
     friend void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline);
 
@@ -54,6 +53,16 @@ class RegexGenerator : private MacroAssembler {
     static const RegisterID regT1 = ARMRegisters::r6;
 
     static const RegisterID returnRegister = ARMRegisters::r0;
     static const RegisterID regT1 = ARMRegisters::r6;
 
     static const RegisterID returnRegister = ARMRegisters::r0;
+#elif CPU(MIPS)
+    static const RegisterID input = MIPSRegisters::a0;
+    static const RegisterID index = MIPSRegisters::a1;
+    static const RegisterID length = MIPSRegisters::a2;
+    static const RegisterID output = MIPSRegisters::a3;
+
+    static const RegisterID regT0 = MIPSRegisters::t4;
+    static const RegisterID regT1 = MIPSRegisters::t5;
+
+    static const RegisterID returnRegister = MIPSRegisters::v0;
 #elif CPU(X86)
     static const RegisterID input = X86Registers::eax;
     static const RegisterID index = X86Registers::edx;
 #elif CPU(X86)
     static const RegisterID input = X86Registers::eax;
     static const RegisterID index = X86Registers::edx;
@@ -145,6 +154,11 @@ class RegexGenerator : private MacroAssembler {
 
     void matchCharacterClass(RegisterID character, JumpList& matchDest, const CharacterClass* charClass)
     {
 
     void matchCharacterClass(RegisterID character, JumpList& matchDest, const CharacterClass* charClass)
     {
+        if (charClass->m_table) {
+            ExtendedAddress tableEntry(character, reinterpret_cast<intptr_t>(charClass->m_table->m_table));
+            matchDest.append(branchTest8(charClass->m_table->m_inverted ? Zero : NonZero, tableEntry));   
+            return;
+        }
         Jump unicodeFail;
         if (charClass->m_matchesUnicode.size() || charClass->m_rangesUnicode.size()) {
             Jump isAscii = branch32(LessThanOrEqual, character, Imm32(0x7f));
         Jump unicodeFail;
         if (charClass->m_matchesUnicode.size() || charClass->m_rangesUnicode.size()) {
             Jump isAscii = branch32(LessThanOrEqual, character, Imm32(0x7f));
@@ -599,9 +613,14 @@ class RegexGenerator : private MacroAssembler {
             ASSERT(!m_pattern.m_ignoreCase || (Unicode::toLower(ch) == Unicode::toUpper(ch)));
             failures.append(jumpIfCharNotEquals(ch, state.inputOffset()));
         }
             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);
         add32(Imm32(1), countRegister);
         add32(Imm32(1), index);
-        branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this);
+        if (term.quantityCount != 0xffffffff)
+            branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this);
+        else
+            jump(loop);
+
         failures.append(jump());
 
         Label backtrackBegin(this);
         failures.append(jump());
 
         Label backtrackBegin(this);
@@ -636,7 +655,8 @@ class RegexGenerator : private MacroAssembler {
         loadFromFrame(term.frameLocation, countRegister);
 
         atEndOfInput().linkTo(hardFail, this);
         loadFromFrame(term.frameLocation, countRegister);
 
         atEndOfInput().linkTo(hardFail, this);
-        branch32(Equal, countRegister, Imm32(term.quantityCount), hardFail);
+        if (term.quantityCount != 0xffffffff)
+            branch32(Equal, countRegister, Imm32(term.quantityCount), hardFail);
         if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
             readCharacter(state.inputOffset(), character);
             or32(Imm32(32), character);
         if (m_pattern.m_ignoreCase && isASCIIAlpha(ch)) {
             readCharacter(state.inputOffset(), character);
             or32(Imm32(32), character);
@@ -722,7 +742,11 @@ class RegexGenerator : private MacroAssembler {
 
         add32(Imm32(1), countRegister);
         add32(Imm32(1), index);
 
         add32(Imm32(1), countRegister);
         add32(Imm32(1), index);
-        branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this);
+        if (term.quantityCount != 0xffffffff)
+            branch32(NotEqual, countRegister, Imm32(term.quantityCount)).linkTo(loop, this);
+        else
+            jump(loop);
+
         failures.append(jump());
 
         Label backtrackBegin(this);
         failures.append(jump());
 
         Label backtrackBegin(this);
@@ -1078,17 +1102,15 @@ class RegexGenerator : private MacroAssembler {
             break;
 
         case PatternTerm::TypeBackReference:
             break;
 
         case PatternTerm::TypeBackReference:
-            m_generationFailed = true;
+            ASSERT_NOT_REACHED();
             break;
 
         case PatternTerm::TypeForwardReference:
             break;
 
         case PatternTerm::TypeParenthesesSubpattern:
             break;
 
         case PatternTerm::TypeForwardReference:
             break;
 
         case PatternTerm::TypeParenthesesSubpattern:
-            if ((term.quantityCount == 1) && !term.parentheses.isCopy)
-                generateParenthesesSingle(state);
-            else
-                m_generationFailed = true;
+            ASSERT((term.quantityCount == 1) && !term.parentheses.isCopy); // must fallback to pcre before this point
+            generateParenthesesSingle(state);
             break;
 
         case PatternTerm::TypeParentheticalAssertion:
             break;
 
         case PatternTerm::TypeParentheticalAssertion:
@@ -1313,6 +1335,8 @@ class RegexGenerator : private MacroAssembler {
         push(ARMRegisters::r5);
         push(ARMRegisters::r6);
         move(ARMRegisters::r3, output);
         push(ARMRegisters::r5);
         push(ARMRegisters::r6);
         move(ARMRegisters::r3, output);
+#elif CPU(MIPS)
+        // Do nothing.
 #endif
     }
 
 #endif
     }
 
@@ -1330,6 +1354,8 @@ class RegexGenerator : private MacroAssembler {
         pop(ARMRegisters::r6);
         pop(ARMRegisters::r5);
         pop(ARMRegisters::r4);
         pop(ARMRegisters::r6);
         pop(ARMRegisters::r5);
         pop(ARMRegisters::r4);
+#elif CPU(MIPS)
+        // Do nothing
 #endif
         ret();
     }
 #endif
         ret();
     }
@@ -1337,7 +1363,6 @@ class RegexGenerator : private MacroAssembler {
 public:
     RegexGenerator(RegexPattern& pattern)
         : m_pattern(pattern)
 public:
     RegexGenerator(RegexPattern& pattern)
         : m_pattern(pattern)
-        , m_generationFailed(false)
     {
     }
 
     {
     }
 
@@ -1367,34 +1392,27 @@ public:
         jitObject.set(patchBuffer.finalizeCode());
     }
 
         jitObject.set(patchBuffer.finalizeCode());
     }
 
-    bool generationFailed()
-    {
-        return m_generationFailed;
-    }
-
 private:
     RegexPattern& m_pattern;
     Vector<AlternativeBacktrackRecord> m_backtrackRecords;
 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);
 };
 
 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;
     if ((error = compileRegex(patternString, pattern)))
         return;
-
     numSubpatterns = pattern.m_numSubpatterns;
 
     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));
+    if (!pattern.m_shouldFallBack && globalData->canUseJIT()) {
+        RegexGenerator generator(pattern);
+        generator.compile(globalData, jitObject);
+        return;
     }
     }
+
+    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));
 }
 
 }}
 }
 
 }}
index 935b9a3a18c18e51d1dbb71553d540bb97c99fd3..7f9c16e09dfcce0e89ac7a78228af266df6ec1b0 100644 (file)
@@ -26,8 +26,6 @@
 #ifndef RegexJIT_h
 #define RegexJIT_h
 
 #ifndef RegexJIT_h
 #define RegexJIT_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(YARR_JIT)
 
 #include "MacroAssembler.h"
 #if ENABLE(YARR_JIT)
 
 #include "MacroAssembler.h"
@@ -68,7 +66,7 @@ public:
     JSRegExp* getFallback() { return m_fallback; }
     void setFallback(JSRegExp* fallback) { m_fallback = fallback; }
 
     JSRegExp* getFallback() { return m_fallback; }
     void setFallback(JSRegExp* fallback) { m_fallback = fallback; }
 
-    bool operator!() { return !m_ref.m_code.executableAddress(); }
+    bool operator!() { return (!m_ref.m_code.executableAddress() && !m_fallback); }
     void set(MacroAssembler::CodeRef ref) { m_ref = ref; }
 
     int execute(const UChar* input, unsigned start, unsigned length, int* output)
     void set(MacroAssembler::CodeRef ref) { m_ref = ref; }
 
     int execute(const UChar* input, unsigned start, unsigned length, int* output)
index 64e846305480d37d211d24ad3094e30c1538631d..c946c2e8e48b2310eae3d323ee2954bc0a76f44c 100644 (file)
 #ifndef RegexParser_h
 #define RegexParser_h
 
 #ifndef RegexParser_h
 #define RegexParser_h
 
-#include <wtf/Platform.h>
-
 #if ENABLE(YARR)
 
 #include <UString.h>
 #if ENABLE(YARR)
 
 #include <UString.h>
+#include <limits.h>
 #include <wtf/ASCIICType.h>
 #include <wtf/unicode/Unicode.h>
 #include <wtf/ASCIICType.h>
 #include <wtf/unicode/Unicode.h>
-#include <limits.h>
 
 namespace JSC { namespace Yarr {
 
 
 namespace JSC { namespace Yarr {
 
index dd7512d0b11c1231884077e03bab12e4d3225b7e..3271cc162bf4ff078b8e5295ceb9cd751678157a 100644 (file)
@@ -26,7 +26,6 @@
 #ifndef RegexPattern_h
 #define RegexPattern_h
 
 #ifndef RegexPattern_h
 #define RegexPattern_h
 
-#include <wtf/Platform.h>
 
 #if ENABLE(YARR)
 
 
 #if ENABLE(YARR)
 
@@ -57,11 +56,35 @@ struct CharacterRange {
     }
 };
 
     }
 };
 
+struct CharacterClassTable : RefCounted<CharacterClassTable> {
+    const char* m_table;
+    bool m_inverted;
+    static PassRefPtr<CharacterClassTable> create(const char* table, bool inverted)
+    {
+        return adoptRef(new CharacterClassTable(table, inverted));
+    }
+
+private:
+    CharacterClassTable(const char* table, bool inverted)
+        : m_table(table)
+        , m_inverted(inverted)
+    {
+    }
+};
+
 struct CharacterClass : FastAllocBase {
 struct CharacterClass : FastAllocBase {
+    // All CharacterClass instances have to have the full set of matches and ranges,
+    // they may have an optional table for faster lookups (which must match the
+    // specified matches and ranges)
+    CharacterClass(PassRefPtr<CharacterClassTable> table)
+        : m_table(table)
+    {
+    }
     Vector<UChar> m_matches;
     Vector<CharacterRange> m_ranges;
     Vector<UChar> m_matchesUnicode;
     Vector<CharacterRange> m_rangesUnicode;
     Vector<UChar> m_matches;
     Vector<CharacterRange> m_ranges;
     Vector<UChar> m_matchesUnicode;
     Vector<CharacterRange> m_rangesUnicode;
+    RefPtr<CharacterClassTable> m_table;
 };
 
 enum QuantifierType {
 };
 
 enum QuantifierType {
@@ -248,6 +271,7 @@ struct RegexPattern {
         , m_multiline(multiline)
         , m_numSubpatterns(0)
         , m_maxBackReference(0)
         , m_multiline(multiline)
         , m_numSubpatterns(0)
         , m_maxBackReference(0)
+        , m_shouldFallBack(false)
         , newlineCached(0)
         , digitsCached(0)
         , spacesCached(0)
         , newlineCached(0)
         , digitsCached(0)
         , spacesCached(0)
@@ -269,6 +293,8 @@ struct RegexPattern {
         m_numSubpatterns = 0;
         m_maxBackReference = 0;
 
         m_numSubpatterns = 0;
         m_maxBackReference = 0;
 
+        m_shouldFallBack = false;
+
         newlineCached = 0;
         digitsCached = 0;
         spacesCached = 0;
         newlineCached = 0;
         digitsCached = 0;
         spacesCached = 0;
@@ -335,6 +361,7 @@ struct RegexPattern {
     bool m_multiline;
     unsigned m_numSubpatterns;
     unsigned m_maxBackReference;
     bool m_multiline;
     unsigned m_numSubpatterns;
     unsigned m_maxBackReference;
+    bool m_shouldFallBack;
     PatternDisjunction* m_body;
     Vector<PatternDisjunction*, 4> m_disjunctions;
     Vector<CharacterClass*> m_userCharacterClasses;
     PatternDisjunction* m_body;
     Vector<PatternDisjunction*, 4> m_disjunctions;
     Vector<CharacterClass*> m_userCharacterClasses;