summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-04-27 16:31:00 +0100
committerSteve Block <steveblock@google.com>2010-05-11 14:42:12 +0100
commitdcc8cf2e65d1aa555cce12431a16547e66b469ee (patch)
tree92a8d65cd5383bca9749f5327fb5e440563926e6 /JavaScriptCore
parentccac38a6b48843126402088a309597e682f40fe6 (diff)
downloadexternal_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz
external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'JavaScriptCore')
-rw-r--r--JavaScriptCore/API/APICast.h1
-rw-r--r--JavaScriptCore/API/APIShims.h9
-rw-r--r--JavaScriptCore/API/JSCallbackFunction.cpp1
-rw-r--r--JavaScriptCore/API/JSCallbackObject.h124
-rw-r--r--JavaScriptCore/API/JSCallbackObjectFunctions.h12
-rw-r--r--JavaScriptCore/API/JSClassRef.cpp8
-rw-r--r--JavaScriptCore/API/JSContextRef.cpp35
-rw-r--r--JavaScriptCore/API/JSObjectRef.cpp51
-rw-r--r--JavaScriptCore/API/JSObjectRefPrivate.h74
-rw-r--r--JavaScriptCore/API/JSValueRef.cpp29
-rw-r--r--JavaScriptCore/API/JSValueRef.h23
-rw-r--r--JavaScriptCore/API/JSWeakObjectMapRefInternal.h68
-rw-r--r--JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp83
-rw-r--r--JavaScriptCore/API/JSWeakObjectMapRefPrivate.h95
-rw-r--r--JavaScriptCore/API/WebKitAvailability.h166
-rw-r--r--JavaScriptCore/API/tests/testapi.c102
-rw-r--r--JavaScriptCore/Android.mk13
-rw-r--r--JavaScriptCore/Android.v8.wtf.mk10
-rw-r--r--JavaScriptCore/ChangeLog3699
-rw-r--r--JavaScriptCore/Configurations/Base.xcconfig30
-rw-r--r--JavaScriptCore/Configurations/DebugRelease.xcconfig4
-rw-r--r--JavaScriptCore/Configurations/FeatureDefines.xcconfig11
-rw-r--r--JavaScriptCore/Configurations/JavaScriptCore.xcconfig7
-rw-r--r--JavaScriptCore/Configurations/Version.xcconfig4
-rw-r--r--JavaScriptCore/DerivedSources.make5
-rw-r--r--JavaScriptCore/DerivedSources.pro8
-rw-r--r--JavaScriptCore/GNUmakefile.am43
-rw-r--r--JavaScriptCore/JavaScriptCore.exp172
-rw-r--r--JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp2
-rw-r--r--JavaScriptCore/JavaScriptCore.gypi33
-rw-r--r--JavaScriptCore/JavaScriptCore.pri222
-rw-r--r--JavaScriptCore/JavaScriptCore.pro221
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def161
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj96
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops4
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make4
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj48
-rw-r--r--JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops4
-rw-r--r--JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj170
-rw-r--r--JavaScriptCore/assembler/ARMAssembler.cpp15
-rw-r--r--JavaScriptCore/assembler/ARMAssembler.h5
-rw-r--r--JavaScriptCore/assembler/ARMv7Assembler.h56
-rw-r--r--JavaScriptCore/assembler/AbstractMacroAssembler.h20
-rw-r--r--JavaScriptCore/assembler/AssemblerBuffer.h2
-rw-r--r--JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h2
-rw-r--r--JavaScriptCore/assembler/CodeLocation.h1
-rw-r--r--JavaScriptCore/assembler/LinkBuffer.h2
-rw-r--r--JavaScriptCore/assembler/MIPSAssembler.h944
-rw-r--r--JavaScriptCore/assembler/MacroAssembler.h13
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerARM.h26
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerARMv7.h58
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerCodeRef.h2
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerMIPS.h1711
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerX86.h2
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerX86Common.h40
-rw-r--r--JavaScriptCore/assembler/MacroAssemblerX86_64.h10
-rw-r--r--JavaScriptCore/assembler/RepatchBuffer.h2
-rw-r--r--JavaScriptCore/assembler/X86Assembler.h29
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.cpp208
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.h11
-rw-r--r--JavaScriptCore/bytecode/EvalCodeCache.h1
-rw-r--r--JavaScriptCore/bytecode/Instruction.h3
-rw-r--r--JavaScriptCore/bytecode/JumpTable.cpp2
-rw-r--r--JavaScriptCore/bytecode/Opcode.h6
-rw-r--r--JavaScriptCore/bytecode/SamplingTool.cpp2
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.cpp24
-rw-r--r--JavaScriptCore/bytecompiler/BytecodeGenerator.h3
-rw-r--r--JavaScriptCore/bytecompiler/NodesCodegen.cpp4
-rw-r--r--JavaScriptCore/config.h8
-rwxr-xr-xJavaScriptCore/create_hash_table5
-rw-r--r--JavaScriptCore/create_regex_tables112
-rw-r--r--JavaScriptCore/interpreter/Interpreter.cpp239
-rw-r--r--JavaScriptCore/interpreter/Interpreter.h2
-rw-r--r--JavaScriptCore/jit/ExecutableAllocator.h30
-rw-r--r--JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp4
-rw-r--r--JavaScriptCore/jit/JIT.cpp6
-rw-r--r--JavaScriptCore/jit/JIT.h97
-rw-r--r--JavaScriptCore/jit/JITArithmetic.cpp5
-rw-r--r--JavaScriptCore/jit/JITCall.cpp2
-rw-r--r--JavaScriptCore/jit/JITCode.h2
-rw-r--r--JavaScriptCore/jit/JITInlineMethods.h18
-rw-r--r--JavaScriptCore/jit/JITOpcodes.cpp150
-rw-r--r--JavaScriptCore/jit/JITPropertyAccess.cpp161
-rw-r--r--JavaScriptCore/jit/JITPropertyAccess32_64.cpp161
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp566
-rw-r--r--JavaScriptCore/jit/JITStubs.h39
-rw-r--r--JavaScriptCore/jsc.cpp14
-rw-r--r--JavaScriptCore/jsc.pro6
-rwxr-xr-xJavaScriptCore/make-generated-sources.sh1
-rw-r--r--JavaScriptCore/os-win32/stdint.h4
-rw-r--r--JavaScriptCore/parser/Grammar.y17
-rw-r--r--JavaScriptCore/parser/NodeConstructors.h6
-rw-r--r--JavaScriptCore/parser/Nodes.h6
-rw-r--r--JavaScriptCore/parser/Parser.cpp3
-rw-r--r--JavaScriptCore/pcre/pcre_exec.cpp2
-rw-r--r--JavaScriptCore/profiler/CallIdentifier.h4
-rw-r--r--JavaScriptCore/profiler/Profile.cpp2
-rw-r--r--JavaScriptCore/profiler/ProfileGenerator.cpp4
-rw-r--r--JavaScriptCore/profiler/ProfileNode.cpp9
-rw-r--r--JavaScriptCore/qt/api/QtScript.pro12
-rw-r--r--JavaScriptCore/qt/api/qscriptconverter_p.h82
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.cpp78
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.h10
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.cpp40
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.h44
-rw-r--r--JavaScriptCore/qt/api/qscriptprogram.cpp136
-rw-r--r--JavaScriptCore/qt/api/qscriptprogram.h53
-rw-r--r--JavaScriptCore/qt/api/qscriptprogram_p.h129
-rw-r--r--JavaScriptCore/qt/api/qscriptstring.cpp131
-rw-r--r--JavaScriptCore/qt/api/qscriptstring.h58
-rw-r--r--JavaScriptCore/qt/api/qscriptstring_p.h112
-rw-r--r--JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp148
-rw-r--r--JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h50
-rw-r--r--JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h73
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue_p.h96
-rw-r--r--JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro1
-rw-r--r--JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp231
-rw-r--r--JavaScriptCore/qt/tests/qscriptstring/qscriptstring.pro7
-rw-r--r--JavaScriptCore/qt/tests/qscriptstring/tst_qscriptstring.cpp175
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro1
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp4
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h11
-rw-r--r--JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp488
-rw-r--r--JavaScriptCore/qt/tests/tests.pri9
-rw-r--r--JavaScriptCore/qt/tests/tests.pro3
-rw-r--r--JavaScriptCore/runtime/ArrayPrototype.cpp43
-rw-r--r--JavaScriptCore/runtime/Collector.cpp65
-rw-r--r--JavaScriptCore/runtime/Collector.h13
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.cpp3
-rw-r--r--JavaScriptCore/runtime/CommonIdentifiers.h1
-rw-r--r--JavaScriptCore/runtime/Completion.cpp12
-rw-r--r--JavaScriptCore/runtime/Completion.h2
-rw-r--r--JavaScriptCore/runtime/DateConversion.cpp2
-rw-r--r--JavaScriptCore/runtime/DatePrototype.cpp3
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.cpp19
-rw-r--r--JavaScriptCore/runtime/ExceptionHelpers.h1
-rw-r--r--JavaScriptCore/runtime/FunctionPrototype.cpp2
-rw-r--r--JavaScriptCore/runtime/GetterSetter.h1
-rw-r--r--JavaScriptCore/runtime/Identifier.cpp154
-rw-r--r--JavaScriptCore/runtime/Identifier.h85
-rw-r--r--JavaScriptCore/runtime/InitializeThreading.cpp2
-rw-r--r--JavaScriptCore/runtime/InternalFunction.cpp2
-rw-r--r--JavaScriptCore/runtime/JSAPIValueWrapper.h2
-rw-r--r--JavaScriptCore/runtime/JSActivation.cpp4
-rw-r--r--JavaScriptCore/runtime/JSActivation.h2
-rw-r--r--JavaScriptCore/runtime/JSArray.cpp12
-rw-r--r--JavaScriptCore/runtime/JSArray.h6
-rw-r--r--JavaScriptCore/runtime/JSCell.cpp10
-rw-r--r--JavaScriptCore/runtime/JSCell.h7
-rw-r--r--JavaScriptCore/runtime/JSFunction.cpp18
-rw-r--r--JavaScriptCore/runtime/JSFunction.h6
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.cpp24
-rw-r--r--JavaScriptCore/runtime/JSGlobalData.h19
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.cpp6
-rw-r--r--JavaScriptCore/runtime/JSGlobalObject.h13
-rw-r--r--JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp10
-rw-r--r--JavaScriptCore/runtime/JSImmediate.h2
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.cpp5
-rw-r--r--JavaScriptCore/runtime/JSNumberCell.h1
-rw-r--r--JavaScriptCore/runtime/JSONObject.cpp9
-rw-r--r--JavaScriptCore/runtime/JSONObject.h2
-rw-r--r--JavaScriptCore/runtime/JSObject.h57
-rw-r--r--JavaScriptCore/runtime/JSPropertyNameIterator.h11
-rw-r--r--JavaScriptCore/runtime/JSString.cpp40
-rw-r--r--JavaScriptCore/runtime/JSString.h47
-rw-r--r--JavaScriptCore/runtime/JSStringBuilder.h54
-rw-r--r--JavaScriptCore/runtime/JSTypeInfo.h8
-rw-r--r--JavaScriptCore/runtime/JSValue.h2
-rw-r--r--JavaScriptCore/runtime/JSZombie.h2
-rw-r--r--JavaScriptCore/runtime/Lookup.h4
-rw-r--r--JavaScriptCore/runtime/MathObject.cpp3
-rw-r--r--JavaScriptCore/runtime/NumberConstructor.cpp21
-rw-r--r--JavaScriptCore/runtime/NumericStrings.h23
-rw-r--r--JavaScriptCore/runtime/PropertyNameArray.cpp2
-rw-r--r--JavaScriptCore/runtime/PropertySlot.cpp8
-rw-r--r--JavaScriptCore/runtime/PropertySlot.h74
-rw-r--r--JavaScriptCore/runtime/RegExp.cpp49
-rw-r--r--JavaScriptCore/runtime/RegExp.h5
-rw-r--r--JavaScriptCore/runtime/RegExpConstructor.cpp99
-rw-r--r--JavaScriptCore/runtime/RegExpMatchesArray.h16
-rw-r--r--JavaScriptCore/runtime/RegExpObject.cpp31
-rw-r--r--JavaScriptCore/runtime/RopeImpl.cpp (renamed from JavaScriptCore/wrec/Quantifier.h)80
-rw-r--r--JavaScriptCore/runtime/RopeImpl.h88
-rw-r--r--JavaScriptCore/runtime/SmallStrings.cpp6
-rw-r--r--JavaScriptCore/runtime/StringBuilder.h3
-rw-r--r--JavaScriptCore/runtime/StringPrototype.cpp1
-rw-r--r--JavaScriptCore/runtime/Structure.cpp4
-rw-r--r--JavaScriptCore/runtime/Terminator.h47
-rw-r--r--JavaScriptCore/runtime/TimeoutChecker.cpp7
-rw-r--r--JavaScriptCore/runtime/UString.cpp163
-rw-r--r--JavaScriptCore/runtime/UString.h98
-rw-r--r--JavaScriptCore/runtime/UStringImpl.cpp152
-rw-r--r--JavaScriptCore/runtime/UStringImpl.h369
-rw-r--r--JavaScriptCore/runtime/WeakGCPtr.h4
-rw-r--r--JavaScriptCore/tests/perf/bench-allocate-nonretained.js6
-rw-r--r--JavaScriptCore/tests/perf/bench-allocate-retained.js10
-rw-r--r--JavaScriptCore/wrec/CharacterClass.cpp140
-rw-r--r--JavaScriptCore/wrec/CharacterClassConstructor.cpp257
-rw-r--r--JavaScriptCore/wrec/CharacterClassConstructor.h99
-rw-r--r--JavaScriptCore/wrec/Escapes.h150
-rw-r--r--JavaScriptCore/wrec/WREC.cpp86
-rw-r--r--JavaScriptCore/wrec/WRECFunctors.cpp80
-rw-r--r--JavaScriptCore/wrec/WRECFunctors.h109
-rw-r--r--JavaScriptCore/wrec/WRECGenerator.cpp653
-rw-r--r--JavaScriptCore/wrec/WRECGenerator.h128
-rw-r--r--JavaScriptCore/wrec/WRECParser.cpp643
-rw-r--r--JavaScriptCore/wrec/WRECParser.h214
-rw-r--r--JavaScriptCore/wscript6
-rw-r--r--JavaScriptCore/wtf/ASCIICType.h1
-rw-r--r--JavaScriptCore/wtf/AlwaysInline.h10
-rw-r--r--JavaScriptCore/wtf/Assertions.h15
-rw-r--r--JavaScriptCore/wtf/FastMalloc.cpp226
-rw-r--r--JavaScriptCore/wtf/FastMalloc.h24
-rw-r--r--JavaScriptCore/wtf/HashCountedSet.h39
-rw-r--r--JavaScriptCore/wtf/HashMap.h3
-rw-r--r--JavaScriptCore/wtf/MathExtras.h2
-rw-r--r--JavaScriptCore/wtf/OwnFastMallocPtr.h2
-rw-r--r--JavaScriptCore/wtf/OwnPtr.h3
-rw-r--r--JavaScriptCore/wtf/OwnPtrBrew.cpp (renamed from JavaScriptCore/wrec/WREC.h)49
-rw-r--r--JavaScriptCore/wtf/OwnPtrCommon.h15
-rw-r--r--JavaScriptCore/wtf/PassRefPtr.h15
-rw-r--r--JavaScriptCore/wtf/Platform.h85
-rw-r--r--JavaScriptCore/wtf/StaticConstructors.h80
-rw-r--r--JavaScriptCore/wtf/StdLibExtras.h1
-rw-r--r--JavaScriptCore/wtf/TCSystemAlloc.cpp3
-rw-r--r--JavaScriptCore/wtf/Threading.h6
-rw-r--r--JavaScriptCore/wtf/VMTags.h55
-rw-r--r--JavaScriptCore/wtf/ValueCheck.h15
-rw-r--r--JavaScriptCore/wtf/Vector.h82
-rw-r--r--JavaScriptCore/wtf/VectorTraits.h3
-rw-r--r--JavaScriptCore/wtf/WTFThreadData.cpp (renamed from JavaScriptCore/wrec/CharacterClass.h)78
-rw-r--r--JavaScriptCore/wtf/WTFThreadData.h165
-rw-r--r--JavaScriptCore/wtf/brew/OwnPtrBrew.cpp51
-rw-r--r--JavaScriptCore/wtf/brew/OwnPtrBrew.h133
-rw-r--r--JavaScriptCore/wtf/brew/ShellBrew.h56
-rw-r--r--JavaScriptCore/wtf/brew/SystemMallocBrew.h65
-rw-r--r--JavaScriptCore/wtf/efl/MainThreadEfl.cpp57
-rw-r--r--JavaScriptCore/wtf/gobject/GOwnPtr.cpp (renamed from JavaScriptCore/wtf/gtk/GOwnPtr.cpp)0
-rw-r--r--JavaScriptCore/wtf/gobject/GOwnPtr.h (renamed from JavaScriptCore/wtf/gtk/GOwnPtr.h)0
-rw-r--r--JavaScriptCore/wtf/gobject/GRefPtr.cpp (renamed from JavaScriptCore/wtf/gtk/GRefPtr.cpp)0
-rw-r--r--JavaScriptCore/wtf/gobject/GRefPtr.h (renamed from JavaScriptCore/wtf/gtk/GRefPtr.h)0
-rw-r--r--JavaScriptCore/wtf/mac/MainThreadMac.mm29
-rw-r--r--JavaScriptCore/wtf/qt/StringQt.cpp72
-rw-r--r--JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp132
-rw-r--r--JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h120
-rw-r--r--JavaScriptCore/wtf/text/AtomicString.cpp327
-rw-r--r--JavaScriptCore/wtf/text/AtomicString.h166
-rw-r--r--JavaScriptCore/wtf/text/AtomicStringImpl.h36
-rw-r--r--JavaScriptCore/wtf/text/CString.cpp102
-rw-r--r--JavaScriptCore/wtf/text/CString.h81
-rw-r--r--JavaScriptCore/wtf/text/StringBuffer.h77
-rw-r--r--JavaScriptCore/wtf/text/StringHash.h268
-rw-r--r--JavaScriptCore/wtf/text/StringImpl.cpp953
-rw-r--r--JavaScriptCore/wtf/text/StringImpl.h389
-rw-r--r--JavaScriptCore/wtf/text/StringImplBase.h103
-rw-r--r--JavaScriptCore/wtf/text/WTFString.cpp960
-rw-r--r--JavaScriptCore/wtf/text/WTFString.h398
-rw-r--r--JavaScriptCore/wtf/unicode/Collator.h4
-rw-r--r--JavaScriptCore/wtf/unicode/CollatorDefault.cpp4
-rw-r--r--JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h2
-rw-r--r--JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp8
-rw-r--r--JavaScriptCore/yarr/RegexCompiler.cpp107
-rw-r--r--JavaScriptCore/yarr/RegexCompiler.h4
-rw-r--r--JavaScriptCore/yarr/RegexInterpreter.cpp31
-rw-r--r--JavaScriptCore/yarr/RegexInterpreter.h4
-rw-r--r--JavaScriptCore/yarr/RegexJIT.cpp59
-rw-r--r--JavaScriptCore/yarr/RegexJIT.h4
-rw-r--r--JavaScriptCore/yarr/RegexParser.h4
-rw-r--r--JavaScriptCore/yarr/RegexPattern.h29
269 files changed, 17805 insertions, 5657 deletions
diff --git a/JavaScriptCore/API/APICast.h b/JavaScriptCore/API/APICast.h
index 4284c44..ba00d02 100644
--- a/JavaScriptCore/API/APICast.h
+++ b/JavaScriptCore/API/APICast.h
@@ -29,7 +29,6 @@
#include "JSAPIValueWrapper.h"
#include "JSGlobalObject.h"
#include "JSValue.h"
-#include <wtf/Platform.h>
#include <wtf/UnusedParam.h>
namespace JSC {
diff --git a/JavaScriptCore/API/APIShims.h b/JavaScriptCore/API/APIShims.h
index 9a6cacb..3d42ca2 100644
--- a/JavaScriptCore/API/APIShims.h
+++ b/JavaScriptCore/API/APIShims.h
@@ -28,6 +28,7 @@
#include "CallFrame.h"
#include "JSLock.h"
+#include <wtf/WTFThreadData.h>
namespace JSC {
@@ -35,7 +36,7 @@ class APIEntryShimWithoutLock {
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();
@@ -45,7 +46,7 @@ protected:
~APIEntryShimWithoutLock()
{
m_globalData->timeoutChecker.stop();
- setCurrentIdentifierTable(m_entryIdentifierTable);
+ wtfThreadData().setCurrentIdentifierTable(m_entryIdentifierTable);
}
private:
@@ -79,12 +80,12 @@ public:
: m_dropAllLocks(exec)
, m_globalData(&exec->globalData())
{
- resetCurrentIdentifierTable();
+ wtfThreadData().resetCurrentIdentifierTable();
}
~APICallbackShim()
{
- setCurrentIdentifierTable(m_globalData->identifierTable);
+ wtfThreadData().setCurrentIdentifierTable(m_globalData->identifierTable);
}
private:
diff --git a/JavaScriptCore/API/JSCallbackFunction.cpp b/JavaScriptCore/API/JSCallbackFunction.cpp
index 0e434d9..63c8add 100644
--- a/JavaScriptCore/API/JSCallbackFunction.cpp
+++ b/JavaScriptCore/API/JSCallbackFunction.cpp
@@ -24,7 +24,6 @@
*/
#include "config.h"
-#include <wtf/Platform.h>
#include "JSCallbackFunction.h"
#include "APIShims.h"
diff --git a/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h
index adb5b60..1cf7a02 100644
--- a/JavaScriptCore/API/JSCallbackObject.h
+++ b/JavaScriptCore/API/JSCallbackObject.h
@@ -33,6 +33,84 @@
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:
@@ -52,6 +130,21 @@ public:
{
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;
@@ -79,6 +172,12 @@ private:
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);
@@ -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 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;
};
diff --git a/JavaScriptCore/API/JSCallbackObjectFunctions.h b/JavaScriptCore/API/JSCallbackObjectFunctions.h
index 4b28a99..6c83eb4 100644
--- a/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -516,9 +516,9 @@ bool JSCallbackObject<Base>::inherits(JSClassRef c) const
}
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;
@@ -547,9 +547,9 @@ JSValue JSCallbackObject<Base>::staticValueGetter(ExecState* exec, const Identif
}
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);
@@ -572,9 +572,9 @@ JSValue JSCallbackObject<Base>::staticFunctionGetter(ExecState* exec, const Iden
}
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;
diff --git a/JavaScriptCore/API/JSClassRef.cpp b/JavaScriptCore/API/JSClassRef.cpp
index 717488f..3e65b75 100644
--- a/JavaScriptCore/API/JSClassRef.cpp
+++ b/JavaScriptCore/API/JSClassRef.cpp
@@ -33,6 +33,7 @@
#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;
@@ -111,7 +112,8 @@ OpaqueJSClass::OpaqueJSClass(const JSClassDefinition* definition, 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();
@@ -171,7 +173,7 @@ 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);
- staticValues->add(UString::Rep::create(it->first->data(), it->first->length()), entry);
+ staticValues->add(UString::Rep::create(it->first->characters(), it->first->length()), entry);
}
} else
staticValues = 0;
@@ -183,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);
- staticFunctions->add(UString::Rep::create(it->first->data(), it->first->length()), entry);
+ staticFunctions->add(UString::Rep::create(it->first->characters(), it->first->length()), entry);
}
} else
diff --git a/JavaScriptCore/API/JSContextRef.cpp b/JavaScriptCore/API/JSContextRef.cpp
index 2c76338..06f9274 100644
--- a/JavaScriptCore/API/JSContextRef.cpp
+++ b/JavaScriptCore/API/JSContextRef.cpp
@@ -33,7 +33,7 @@
#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>
@@ -46,7 +46,7 @@ using namespace JSC;
JSContextGroupRef JSContextGroupCreate()
{
initializeThreading();
- return toRef(JSGlobalData::createNonDefault().releaseRef());
+ return toRef(JSGlobalData::createNonDefault(ThreadStackTypeSmall).releaseRef());
}
JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group)
@@ -84,7 +84,7 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass
initializeThreading();
JSLock lock(LockForReal);
- RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault();
+ RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createNonDefault(ThreadStackTypeSmall);
APIEntryShim entryShim(globalData.get(), false);
@@ -123,19 +123,32 @@ void JSGlobalContextRelease(JSGlobalContextRef ctx)
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();
- } else
+ else if (releasingGlobalObject)
globalData.heap.collectAllGarbage();
globalData.deref();
- setCurrentIdentifierTable(savedIdentifierTable);
+ wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable);
}
JSObjectRef JSContextGetGlobalObject(JSContextRef ctx)
diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp
index faaa4eb..8fdbdab 100644
--- a/JavaScriptCore/API/JSObjectRef.cpp
+++ b/JavaScriptCore/API/JSObjectRef.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "JSObjectRef.h"
+#include "JSObjectRefPrivate.h"
#include "APICast.h"
#include "CodeBlock.h"
@@ -48,7 +49,6 @@
#include "ObjectPrototype.h"
#include "PropertyNameArray.h"
#include "RegExpConstructor.h"
-#include <wtf/Platform.h>
using namespace JSC;
@@ -364,6 +364,55 @@ bool JSObjectSetPrivate(JSObjectRef object, void* data)
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;
diff --git a/JavaScriptCore/API/JSObjectRefPrivate.h b/JavaScriptCore/API/JSObjectRefPrivate.h
new file mode 100644
index 0000000..32e80ab
--- /dev/null
+++ b/JavaScriptCore/API/JSObjectRefPrivate.h
@@ -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
diff --git a/JavaScriptCore/API/JSValueRef.cpp b/JavaScriptCore/API/JSValueRef.cpp
index a12cc34..f5dcccc 100644
--- a/JavaScriptCore/API/JSValueRef.cpp
+++ b/JavaScriptCore/API/JSValueRef.cpp
@@ -26,19 +26,21 @@
#include "config.h"
#include "JSValueRef.h"
-#include <wtf/Platform.h>
#include "APICast.h"
#include "APIShims.h"
#include "JSCallbackObject.h"
#include <runtime/JSGlobalObject.h>
+#include <runtime/JSONObject.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 <wtf/text/StringHash.h>
#include <algorithm> // for std::min
@@ -222,6 +224,31 @@ JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
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);
diff --git a/JavaScriptCore/API/JSValueRef.h b/JavaScriptCore/API/JSValueRef.h
index 7a7bf93..4186db8 100644
--- a/JavaScriptCore/API/JSValueRef.h
+++ b/JavaScriptCore/API/JSValueRef.h
@@ -27,6 +27,7 @@
#define JSValueRef_h
#include <JavaScriptCore/JSBase.h>
+#include <JavaScriptCore/WebKitAvailability.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);
+/* 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 */
/*!
diff --git a/JavaScriptCore/API/JSWeakObjectMapRefInternal.h b/JavaScriptCore/API/JSWeakObjectMapRefInternal.h
new file mode 100644
index 0000000..64e1f4d
--- /dev/null
+++ b/JavaScriptCore/API/JSWeakObjectMapRefInternal.h
@@ -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/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp b/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
new file mode 100644
index 0000000..e377ea0
--- /dev/null
+++ b/JavaScriptCore/API/JSWeakObjectMapRefPrivate.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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>
+
+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/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h b/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h
new file mode 100644
index 0000000..d36111c
--- /dev/null
+++ b/JavaScriptCore/API/JSWeakObjectMapRefPrivate.h
@@ -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
diff --git a/JavaScriptCore/API/WebKitAvailability.h b/JavaScriptCore/API/WebKitAvailability.h
index 8402528..0e4f091 100644
--- a/JavaScriptCore/API/WebKitAvailability.h
+++ b/JavaScriptCore/API/WebKitAvailability.h
@@ -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
@@ -42,7 +42,7 @@
#define WEBKIT_VERSION_LATEST 0x9999
#ifdef __APPLE__
-#import <AvailabilityMacros.h>
+#include <AvailabilityMacros.h>
#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_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
@@ -645,9 +648,9 @@
*
* 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
-#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
@@ -659,7 +662,7 @@
* 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
@@ -671,7 +674,7 @@
* 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
@@ -683,7 +686,7 @@
* 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
@@ -695,7 +698,7 @@
* 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
@@ -707,7 +710,7 @@
* 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
@@ -719,7 +722,7 @@
* 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
@@ -731,7 +734,7 @@
* 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
@@ -743,7 +746,7 @@
* 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
@@ -754,11 +757,148 @@
*
* 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
+
+
+
+
+/*
+ * 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__ */
diff --git a/JavaScriptCore/API/tests/testapi.c b/JavaScriptCore/API/tests/testapi.c
index ebc0cfb..28b4ec8 100644
--- a/JavaScriptCore/API/tests/testapi.c
+++ b/JavaScriptCore/API/tests/testapi.c
@@ -26,6 +26,7 @@
#include "JavaScriptCore.h"
#include "JSBasePrivate.h"
#include "JSContextRefPrivate.h"
+#include "JSObjectRefPrivate.h"
#include <math.h>
#define ASSERT_DISABLED 0
#include <wtf/Assertions.h>
@@ -754,6 +755,8 @@ static void testInitializeFinalize()
static JSValueRef jsNumberValue = NULL;
+static JSObjectRef aHeapRef = NULL;
+
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);
+ 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;
+ 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));
diff --git a/JavaScriptCore/Android.mk b/JavaScriptCore/Android.mk
index b03cd97..2c2a2d0 100644
--- a/JavaScriptCore/Android.mk
+++ b/JavaScriptCore/Android.mk
@@ -153,13 +153,6 @@ LOCAL_SRC_FILES := \
runtime/UString.cpp \
runtime/UStringImpl.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 \
@@ -173,12 +166,18 @@ LOCAL_SRC_FILES := \
wtf/ThreadIdentifierDataPthreads.cpp \
wtf/Threading.cpp \
wtf/ThreadingPthreads.cpp \
+ wtf/WTFThreadData.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 \
\
diff --git a/JavaScriptCore/Android.v8.wtf.mk b/JavaScriptCore/Android.v8.wtf.mk
index 69128d6..9249e47 100644
--- a/JavaScriptCore/Android.v8.wtf.mk
+++ b/JavaScriptCore/Android.v8.wtf.mk
@@ -45,12 +45,18 @@ LOCAL_SRC_FILES := \
wtf/ThreadIdentifierDataPthreads.cpp \
wtf/Threading.cpp \
wtf/ThreadingPthreads.cpp \
- \
- wtf/android/MainThreadAndroid.cpp \
+ wtf/WTFThreadData.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 \
\
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 3d1a925..11f02e3 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,3664 @@
+2010-04-21 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Oliver Hunt.
+
+ Make SmallStrings store an array of RefPtr<StringImpl>,
+ instead of a direct array of StringImpls. This allows
+ us to remove a friend (and a layering violation) from
+ WTF::StringImpl, and makes it so that all StringImpls
+ are individually heap allocated.
+
+ * runtime/SmallStrings.cpp:
+ (JSC::SmallStringsStorage::rep):
+ (JSC::SmallStringsStorage::SmallStringsStorage):
+ * wtf/text/StringImpl.h:
+
+2010-04-21 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Fix for https://bugs.webkit.org/show_bug.cgi?id=37937
+ Wean JavaScriptCore off calls to isMainThread()
+
+ - Replace use of isMainThread() for interpreter reentry checks
+ with a stored value on the JSGlobalData.
+ - Replace use of isMainThread() for useMainThread only check in the
+ collector with a stored exclusive thread.
+
+ * API/JSContextRef.cpp:
+ (JSContextGroupCreate):
+ Always default to a small stack type for uses of the JSC API. It is
+ unlikely that the interpreter reentry required on the web will be as
+ important for other uses of JavaScriptCore.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ Update exports.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ (JSC::Interpreter::prepareForRepeatCall):
+ Use new stored JSGlobalData::maxReentryDepth instead of isMainThread().
+
+ * interpreter/Interpreter.h:
+ Rename MaxMainThreadReentryDepth to MaxLargeThreadReentryDepth and
+ MaxSecondaryThreadReentryDepth to MaxSmallThreadReentryDepth.
+
+ * jsc.cpp:
+ (main): Use the a large stack for jsc since it is always using the
+ main thread.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+ (JSC::arrayProtoFuncToLocaleString):
+ (JSC::arrayProtoFuncJoin):
+ Use new stored JSGlobalData::maxReentryDepth instead of isMainThread().
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::registerThread):
+ Use the concept of making JSC run on an exclusiveThread instead of
+ forcing a mainThreadOnly assertion.
+
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ (JSC::JSGlobalData::createNonDefault):
+ (JSC::JSGlobalData::create):
+ (JSC::JSGlobalData::createLeaked):
+ (JSC::JSGlobalData::sharedInstance):
+ * runtime/JSGlobalData.h:
+ Add ThreadStackType argument to JSGlobalData constructors and set
+ maxReentryDepth based on it.
+
+2010-04-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix pt. 3).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-04-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix pt. 2).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-04-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (Qt build fix).
+
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pro:
+ * wtf/qt/StringQt.cpp: Copied from WebCore/platform/text/qt/StringQt.cpp.
+
+2010-04-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix).
+
+ * API/JSValueRef.cpp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * runtime/Identifier.cpp:
+ (JSC::IdentifierTable::~IdentifierTable):
+ (JSC::IdentifierTable::add):
+ * runtime/Identifier.h:
+ * wtf/WTFThreadData.h:
+ (JSC::IdentifierTable::remove):
+ (JSC::IdentifierTable::literalTable):
+ * wtf/text/StringImpl.cpp:
+ (WebCore::StringImpl::~StringImpl):
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt, Darin Adler.
+
+ Bug 37906 - Remove JSC::UStringImpl; unify with StringImpl.
+
+ JSC::UStringImpl and WebCore::StringImpl (soon to be renamed to
+ WTF::StringImpl) are almost identical. Remove duplication of code by unifying
+ the two, move missing features from UStringImpl into StringImpl & delete the
+ class UStringImpl.
+
+ * API/JSClassRef.cpp:
+ * API/JSContextRef.cpp:
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.pro:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * bytecode/EvalCodeCache.h:
+ * bytecode/JumpTable.cpp:
+ * profiler/ProfileNode.cpp:
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add):
+ * runtime/Identifier.h:
+ (JSC::Identifier::equal):
+ * runtime/UString.cpp:
+ * runtime/UString.h:
+ (WTF::):
+ * runtime/UStringImpl.cpp: Removed.
+ * runtime/UStringImpl.h:
+ * wtf/text/StringHash.h:
+ (WebCore::StringHash::equal):
+ (WebCore::CaseFoldingHash::equal):
+ * wtf/text/StringImpl.cpp:
+ (WebCore::StringImpl::~StringImpl):
+ (WebCore::StringImpl::empty):
+ (WebCore::StringImpl::sharedBuffer):
+ (WebCore::equal):
+ * wtf/text/StringImpl.h:
+ (WebCore::StringImpl::StringImpl):
+ (WebCore::StringImpl::create):
+ (WebCore::StringImpl::tryCreateUninitialized):
+ (WebCore::StringImpl::cost):
+ (WebCore::StringImpl::isIdentifier):
+ (WebCore::StringImpl::setIsIdentifier):
+ (WebCore::StringImpl::computeHash):
+ (WebCore::StringImpl::copyChars):
+ (WebCore::StringImpl::):
+
+2010-04-21 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Darin Adler.
+
+ Added missing #include "Lookup.h" in LUT source files.
+ https://bugs.webkit.org/show_bug.cgi?id=37903
+
+ * runtime/ArrayPrototype.cpp:
+ * runtime/DatePrototype.cpp:
+ * runtime/JSONObject.cpp:
+ * runtime/MathObject.cpp:
+ * runtime/NumberConstructor.cpp:
+ * runtime/RegExpConstructor.cpp:
+ * runtime/RegExpObject.cpp:
+ * runtime/StringPrototype.cpp:
+
+2010-04-21 Gustavo Sverzut Barbieri <barbieri@profusion.mobi>
+
+ Reviewed by Nikolas Zimmermann.
+
+ Add missing EFL JavaScriptCore file.
+ http://webkit.org/b/37854
+
+ * wtf/efl: Added.
+ * wtf/efl/MainThreadEfl.cpp: Added.
+ (WTF::initializeMainThreadPlatform):
+ (WTF::timeoutFired):
+ (WTF::scheduleDispatchFunctionsOnMainThread):
+
+2010-04-20 Xan Lopez <xlopez@igalia.com>
+
+ Another attempt to fix the build.
+
+ * GNUmakefile.am:
+
+2010-04-20 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ [ES5] RegExp literals are constants that should be persistent across multiple function calls.
+ https://bugs.webkit.org/show_bug.cgi?id=37908
+
+ Dump the separate RegExp constant pool, and just use the standard JS constant pool
+ in codeblock. This allows us to drop op_new_regexp and all associated code as well.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::shrinkToFit):
+ * bytecode/CodeBlock.h:
+ * bytecode/Opcode.h:
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::BytecodeGenerator::emitLoad):
+ * bytecompiler/BytecodeGenerator.h:
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::RegExpNode::emitBytecode):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ * jit/JITOpcodes.cpp:
+ * jit/JITStubs.cpp:
+ * jit/JITStubs.h:
+ (JSC::):
+
+2010-04-20 Oliver Hunt <oliver@apple.com>
+
+ Fix license on create_regex_tables
+
+ * create_regex_tables:
+
+2010-04-20 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Fix gtk
+
+ * GNUmakefile.am:
+ * make-generated-sources.sh:
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 37895 - Share common code from UStringImplBase with StringImpl
+
+ The implementation of StringImpl & UStringImpl is very similar. Restructure
+ StringImpl to match UStringImpl, moving the flags and length into a base class,
+ so that this can be shared between both string types to increase code reuse.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/RopeImpl.h:
+ (JSC::RopeImpl::RopeImpl):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::UStringImpl):
+ * wtf/text/StringImpl.h:
+ (WebCore::StringImpl::StringImpl):
+ (WebCore::StringImpl::characters):
+ * wtf/text/StringImplBase.h: Copied from JavaScriptCore/runtime/UStringImpl.h.
+ (WTF::StringImplBase::length):
+ (WTF::StringImplBase::operator new):
+ (WTF::StringImplBase::StringImplBase):
+
+2010-04-20 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Autogenerate yarr character tables
+ https://bugs.webkit.org/show_bug.cgi?id=37877
+
+ Use a python script to automatically generate character tables
+ for the builtin YARR character classes. This allows us to generate
+ actual tables as well, by using these tables we can both increase
+ performance of the check (for complex builtins) and reduce the actual
+ code size.
+
+ 4-8% win on string-unpack-code, but lots of noise on other tests so
+ i'm only confident saying its a 1% win overall.
+
+ * DerivedSources.make:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::ExtendedAddress::ExtendedAddress):
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::branchTest8):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::branchTest8):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::branchTest8):
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::cmpb_im):
+ (JSC::X86Assembler::testb_im):
+ * bytecode/SamplingTool.cpp:
+ (JSC::SamplingTool::dump):
+ * create_regex_tables: Added.
+ * yarr/RegexCompiler.cpp:
+ (JSC::Yarr::CharacterClassConstructor::charClass):
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::matchCharacterClass):
+ (JSC::Yarr::RegexGenerator::generatePatternCharacterGreedy):
+ (JSC::Yarr::RegexGenerator::generatePatternCharacterNonGreedy):
+ (JSC::Yarr::RegexGenerator::generateCharacterClassGreedy):
+ * yarr/RegexPattern.h:
+ (JSC::Yarr::CharacterClassTable::create):
+ (JSC::Yarr::CharacterClassTable::CharacterClassTable):
+ (JSC::Yarr::CharacterClass::CharacterClass):
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (speculative windows fix - missed a bit!).
+
+ * wtf/text/AtomicString.h:
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (speculative windows fix).
+
+ * wtf/text/AtomicString.h:
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix).
+
+ Add missing .def file entries.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 37869 - Move URopeImpl to its own .h/.cpp
+
+ Currently Ropes are implemented by the class URopeImpl, which is defined in
+ UStringImpl.h, and then typedefed to the name JSString::Rope. Remove the
+ typedef, and rename all uses of URopeImpl and JSString::Rope to just RopeImpl.
+
+ Move RopeImpl to its own header, and remove all remaining references to ropes
+ from UStringImpl (rename UStringOrRopeImpl to UStringImplBase, rename or move
+ the isRope & deref methods from UStringOrRopeImpl).
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ * runtime/JSString.h:
+ (JSC::):
+ (JSC::RopeBuilder::JSString):
+ (JSC::RopeBuilder::~JSString):
+ (JSC::RopeBuilder::appendStringInConstruct):
+ (JSC::RopeBuilder::JSStringFinalizerStruct::):
+ * runtime/RopeImpl.cpp: Copied from JavaScriptCore/runtime/UStringImpl.cpp.
+ (JSC::RopeImpl::derefFibersNonRecursive):
+ (JSC::RopeImpl::destructNonRecursive):
+ * runtime/RopeImpl.h: Copied from JavaScriptCore/runtime/UStringImpl.h.
+ (JSC::RopeImpl::tryCreateUninitialized):
+ (JSC::RopeImpl::isRope):
+ (JSC::RopeImpl::deref):
+ (JSC::RopeImpl::RopeImpl):
+ * runtime/UStringImpl.cpp:
+ * runtime/UStringImpl.h:
+ (JSC::UStringImplBase::isInvalid):
+ (JSC::UStringImplBase::ref):
+ (JSC::UStringImplBase::UStringImplBase):
+ (JSC::UStringImplBase::):
+ (JSC::UStringImpl::UStringImpl):
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 37828 - Move WebCore's String classes to WTF
+
+ Move these classes up to WTF so they are available to all clients of WTF (in
+ particular JSC).
+
+ As a first patch, making the most minimal change possible, since this patch
+ could easily grow rather large since we'll have to change every class forward
+ declaration ( e.g. every "namespace WebCore { class String; }" much change to
+ "namespace WTF { class String; }").
+
+ Moving the files, but leaving the classes logically in the WebCore namespace -
+ which is technically a layering violation - I'll come back and fix this up in a
+ subsequent patch.
+
+ * Android.mk:
+ * Android.v8.wtf.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pro:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * config.h:
+ * wtf/StaticConstructors.h: Copied from WebCore/platform/StaticConstructors.h.
+ * wtf/text/AtomicString.cpp: Copied from WebCore/platform/text/AtomicString.cpp.
+ * wtf/text/AtomicString.h: Copied from WebCore/platform/text/AtomicString.h.
+ * wtf/text/AtomicStringImpl.h: Copied from WebCore/platform/text/AtomicStringImpl.h.
+ * wtf/text/StringBuffer.h: Copied from WebCore/platform/text/StringBuffer.h.
+ * wtf/text/StringHash.h: Copied from WebCore/platform/text/StringHash.h.
+ * wtf/text/StringImpl.cpp: Copied from WebCore/platform/text/StringImpl.cpp.
+ * wtf/text/StringImpl.h: Copied from WebCore/platform/text/StringImpl.h.
+ * wtf/text/WTFString.cpp: Copied from WebCore/platform/text/String.cpp.
+ (WebCore::charactersToFloat):
+ * wtf/text/WTFString.h: Copied from WebCore/platform/text/PlatformString.h.
+
+2010-04-20 Csaba Osztrogonác <ossy@webkit.org>
+
+ [Qt] Unreviewed speculative buildfix for WinCE after r57882
+ https://bugs.webkit.org/show_bug.cgi?id=37701
+
+ * JavaScriptCore.pri: missing wince* case added.
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix).
+ Speculative Chromium/Win build fix, attempt #2.
+
+ * config.h:
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix).
+ Speculative Chromium/Win build fix.
+
+ * config.h: JS_EXPORTDATA should do nothing on !JSC builds.
+
+2010-04-20 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Target(WebCore,jsc,...) must depends on static library of JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=37701
+
+ * JavaScriptCore.pri: dependency added.
+
+2010-04-20 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Maciej Stachowiak (relanding r57829).
+ Added missing JS_EXPORTDATA
+
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+ (JSC::APICallbackShim::APICallbackShim):
+ (JSC::APICallbackShim::~APICallbackShim):
+ * API/JSContextRef.cpp:
+ * Android.mk:
+ * Android.v8.wtf.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pro:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::remove):
+ (JSC::Identifier::checkCurrentIdentifierTable):
+ * runtime/Identifier.h:
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::create):
+ * wtf/WTFThreadData.cpp: Copied from JavaScriptCore/wtf/WTFThreadData.cpp.
+ * wtf/WTFThreadData.h: Copied from JavaScriptCore/wtf/WTFThreadData.h.
+
+2010-04-19 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (rolling out r57829).
+ This broke windows.
+
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+ (JSC::APICallbackShim::APICallbackShim):
+ (JSC::APICallbackShim::~APICallbackShim):
+ * API/JSContextRef.cpp:
+ * Android.mk:
+ * Android.v8.wtf.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pro:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::remove):
+ (JSC::Identifier::checkCurrentIdentifierTable):
+ (JSC::createIdentifierTableSpecificCallback):
+ (JSC::createIdentifierTableSpecific):
+ * runtime/Identifier.h:
+ (JSC::ThreadIdentifierTableData::ThreadIdentifierTableData):
+ (JSC::defaultIdentifierTable):
+ (JSC::setDefaultIdentifierTable):
+ (JSC::currentIdentifierTable):
+ (JSC::setCurrentIdentifierTable):
+ (JSC::resetCurrentIdentifierTable):
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::create):
+ * wtf/WTFThreadData.cpp: Removed.
+ * wtf/WTFThreadData.h: Removed.
+
+2010-04-19 Douglas Gregor <dgregor@apple.com>
+
+ Reviewed and landed by Anders Carlsson.
+
+ * runtime/UStringImpl.h:
+ Fix class/struct declaration mismatches.
+
+2010-04-19 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Beth Dakin.
+
+ Checked in these tests I wrote becuase Balazs Kelemen wanted to use them.
+
+ * tests/perf: Added.
+ * tests/perf/bench-allocate-nonretained.js: Added.
+ * tests/perf/bench-allocate-retained.js: Added.
+
+2010-04-19 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-04-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=37745
+ Move string uniquing tables to (new) WTFThreadData class.
+
+ Remove AtomicString's dependency on ThreadGlobalData so that we can move
+ WebCore's string classes up to WTF.
+
+ WTFThreadData.cpp/.h are based on ThreadGlobalData from WebCore.
+ Moved JSC & WebCore's string uniquing tables to this class.
+
+ This patch introduces a temporary layering violation in providing forward
+ declarations of classes from JSC and WTF; this will be resolved as we move
+ more string code up to WTF.
+
+ * API/APIShims.h:
+ (JSC::APIEntryShimWithoutLock::APIEntryShimWithoutLock):
+ (JSC::APIEntryShimWithoutLock::~APIEntryShimWithoutLock):
+ (JSC::APICallbackShim::APICallbackShim):
+ (JSC::APICallbackShim::~APICallbackShim):
+ * API/JSContextRef.cpp:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/Completion.cpp:
+ (JSC::checkSyntax):
+ (JSC::evaluate):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::remove):
+ (JSC::Identifier::checkCurrentIdentifierTable):
+ * runtime/Identifier.h:
+ * runtime/InitializeThreading.cpp:
+ (JSC::initializeThreadingOnce):
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::create):
+ * wtf/WTFThreadData.cpp: Copied from WebCore/platform/ThreadGlobalData.cpp.
+ (WTF::WTFThreadData::WTFThreadData):
+ (WTF::WTFThreadData::~WTFThreadData):
+ * wtf/WTFThreadData.h: Copied from WebCore/platform/ThreadGlobalData.h.
+ (WTF::WTFThreadData::atomicStringTable):
+ (WTF::WTFThreadData::initializeIdentifierTable):
+ (WTF::WTFThreadData::currentIdentifierTable):
+ (WTF::WTFThreadData::setCurrentIdentifierTable):
+ (WTF::WTFThreadData::resetCurrentIdentifierTable):
+ (WTF::wtfThreadData):
+
+2010-04-19 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Build fix for WinCE.
+
+ Moved the include of the non-existing errno.h header file inside
+ platform guard macros.
+
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+
+2010-04-18 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Laszlo Gombos.
+
+ [WINCE] Don't define WTF_CPU_MIDDLE_ENDIAN=1
+ https://bugs.webkit.org/show_bug.cgi?id=37434
+
+ Windows CE supports little-endian format only, so don't define
+ WTF_CPU_MIDDLE_ENDIAN=1.
+
+ * wtf/Platform.h:
+
+2010-04-18 Simon Hausmann <simon.hausmann@nokia.com>
+
+ Reviewed by Laszlo Gombos.
+
+ [Qt] Fix JavaScriptCore's include path for WinCE builds
+
+ https://bugs.webkit.org/show_bug.cgi?id=36751
+
+ * JavaScriptCore.pri:
+
+2010-04-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by nobody, build fix.
+
+2010-04-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by nobody, build fix.
+
+2010-04-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 37730 - Remove JSC::UString dependencies from WebCore::StringImpl
+ (Following on from bug #37675).
+
+ Make the argument ordering for UStringImpl's constructor & create
+ methods match, when passed a shared buffer.
+
+ * JavaScriptCore.exp:
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::create):
+ * runtime/UStringImpl.h:
+
+2010-04-15 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Fix memory leak in QScriptEngine::evaluate().
+
+ QScriptEnginePrivate::evaluate should release temporary variables.
+
+ [Qt] QScriptEngine::evaluate has memory leak.
+ https://bugs.webkit.org/show_bug.cgi?id=37596
+
+ * qt/api/qscriptengine_p.cpp:
+ (QScriptEnginePrivate::evaluate):
+ * qt/api/qscriptengine_p.h:
+
+2010-04-14 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Fix a memory leak in QScriptValue::inherits.
+
+ [Qt] QScriptValue::inherits has a memory leak.
+ https://bugs.webkit.org/show_bug.cgi?id=37617
+
+ * qt/api/qscriptvalue_p.h:
+ (QScriptValuePrivate::inherits):
+
+2010-04-14 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Fix a few memory leaks in QScriptEngine.
+
+ Syntax checking caused memory leak, not all temporary variables were released.
+
+ [Qt] Syntax checking in the QtScript cause a memory leak.
+ https://bugs.webkit.org/show_bug.cgi?id=37610
+
+ * qt/api/qscriptengine_p.cpp:
+ (QScriptEnginePrivate::checkSyntax):
+ * qt/api/qscriptsyntaxcheckresult.cpp:
+ (QScriptSyntaxCheckResultPrivate::errorMessage):
+ (QScriptSyntaxCheckResultPrivate::errorLineNumber):
+
+2010-04-14 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Fix memory leak inside QScriptEnginePrivate::makeJSValue.
+
+ QScriptEnginePrivate::makeJSValue should release temporary JSStringRef variable.
+
+ [Qt] tst_QScriptValue::toString has a memory leak.
+ https://bugs.webkit.org/show_bug.cgi?id=37598
+
+ * qt/api/qscriptengine_p.h:
+ (QScriptEnginePrivate::makeJSValue):
+
+2010-04-14 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by Geoffrey Garen.
+
+ Move the YARR JIT fallback detection from RegexJIT.cpp to
+ RegexCompiler.cpp.
+
+ https://bugs.webkit.org/show_bug.cgi?id=37571
+
+ * yarr/RegexCompiler.cpp:
+ (JSC::Yarr::RegexPatternConstructor::atomBackReference):
+ (JSC::Yarr::RegexPatternConstructor::quantifyAtom):
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateTerm):
+ (JSC::Yarr::RegexGenerator::RegexGenerator):
+ (JSC::Yarr::jitCompileRegex):
+ * yarr/RegexJIT.h:
+ (JSC::Yarr::RegexCodeBlock::operator!):
+ * yarr/RegexPattern.h:
+ (JSC::Yarr::RegexPattern::RegexPattern):
+ (JSC::Yarr::RegexPattern::reset):
+
+2010-04-14 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Mac OS X: Use deployment target to determine whether memory tagging should be enabled
+ https://bugs.webkit.org/show_bug.cgi?id=34888
+
+ When building on (Snow) Leopard but targeting Tiger
+ (TARGETING_TIGER defined, BUILDING_ON_TIGER not defined),
+ WebKit would crash on Tiger because the tags passed to mmap
+ caused those function calls to fail.
+
+ Conversely, when building on Tiger but targeting Leopard
+ (BUILDING_ON_TIGER defined, TARGETING_LEOPARD defined), WebKit
+ would crash on Leopard because the tags passed to vm_map and
+ vm_allocate caused those function calls to fail.
+
+ Solution: Use TARGETING_TIGER rather than BUILDING_ON_TIGER to
+ govern the tag definitions. Use the same tags for vm_map and
+ vm_allocate regardless of target, since they work on
+ both. Fall back to the mmap tags that work on Tiger (that is,
+ "no tags") if targeting Tiger, since those tags also work on
+ Leopard.
+
+ * wtf/VMTags.h:
+
+2010-04-12 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by nobody, build fix.
+
+ [Qt] Build fix for Mac when building with build-webkit --qt
+
+ Specifying no configuration on Mac builds WebCore both in debug
+ and release. JavaScriptCore has to follow this rule as well.
+
+ * JavaScriptCore.pro:
+
+2010-04-11 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ <rdar://problem/7851332> Fix the build.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMallocStats::): Initialize extra members of malloc_introspection_t to zero.
+
+2010-04-09 Mikhail Naganov <mnaganov@chromium.org>
+
+ Reviewed by Pavel Feldman.
+
+ Make CallIdentifier constructor to handle null urls.
+
+ https://bugs.webkit.org/show_bug.cgi?id=37341
+
+ * profiler/CallIdentifier.h:
+ (JSC::CallIdentifier::CallIdentifier):
+
+2010-04-09 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Fix crashes with package builds in release
+
+ Add NDEBUG to the defines for package build in JavaScriptCore.pri,
+ so that it's consistently used for JavaScriptCore, WebCore, jsc and all
+ other tools using wtf, etc. data structures directly. Mixing NDEBUG with
+ non-NDEBUG builds causes crashes due to differences in data structures when
+ assertions/checks are enabled.
+
+ * JavaScriptCore.pri:
+
+2010-04-09 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Darin Adler.
+
+ Implement NO_RETURN for COMPILER(MSVC).
+ https://bugs.webkit.org/show_bug.cgi?id=33056
+
+ Added NO_RETURN_WITH_VALUE for functions with non-void return type.
+
+ * jsc.cpp:
+ * wtf/AlwaysInline.h:
+ * wtf/FastMalloc.cpp:
+
+2010-04-08 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Simon Hausmann.
+
+ [WINCE] Check if ARM or _ARM_ is defined
+ https://bugs.webkit.org/show_bug.cgi?id=37200
+
+ MSVC defines ARM and _ARM_ for Windows CE ARM. Define WTF_CPU_ARM=1
+ when either ARM or _ARM_ is defined.
+
+ * wtf/Platform.h:
+
+2010-04-08 Csaba Osztrogonác <ossy@webkit.org>
+
+ Reviewed Oliver Hunt.
+
+ [Qt]r57240 broke Qt build (might be a gcc bug)
+ https://bugs.webkit.org/show_bug.cgi?id=37253
+
+ Workaround until fix. On PLATFORM(QT) use inline instead of ALWAYS_INLINE.
+
+ * wtf/PassRefPtr.h: Qt guards added.
+
+2010-04-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ Vector<UString> makes many needless calls to UString::UString and UString::~UString
+
+ Add a VectorTrait<UString> specialisation to allow vector to simply memset/memcpy
+ data around. Only difference from the VectorTrait<RefPtr<T> > traits is the inability
+ to use memset to initialize data.
+
+ * runtime/UString.h:
+ (WTF::):
+
+2010-04-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Beat gcc with a clue bat -- force inlining of refIfNotNull and derefIfNotNull
+
+ * wtf/PassRefPtr.h:
+
+2010-04-07 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Darin Adler.
+
+ Replace isprint with isASCIIPrintable
+ https://bugs.webkit.org/show_bug.cgi?id=37223
+
+ WebKit does not use functions in <ctype.h> as they are dependent on the current
+ locale. Use the equivalent functions in <wtf/ASCIICType.h>. isASCIIPrintable
+ replaces isprint.
+
+ * pcre/pcre_exec.cpp:
+ (pchars):
+
+2010-04-07 Enrica Casucci <enrica@apple.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=37219
+
+ This change disables text caret for the iPhone platflorm.
+
+ * wtf/Platform.h: Disabled text caret for iPhone.
+
+2010-04-06 Adam Barth <abarth@webkit.org>
+
+ Reviewed by Eric Seidel.
+
+ REGRESSION: Worker termination via JS timeout may cause worker tests like fast/workers/worker-terminate.html fail.
+ https://bugs.webkit.org/show_bug.cgi?id=36646
+
+ Add a new exception type for forcibly terminating a JavaScript stack.
+ The new exception functions similarly to the
+ InterruptedExecutionException but is conceptually different because
+ execution is terminated instead of just interrupted.
+
+ * GNUmakefile.am:
+ - Added new Terminator.h file.
+ * JavaScriptCore.gypi:
+ - Added new Terminator.h file.
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ - Added new Terminator.h file.
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ - Added new Terminator.h file.
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::throwException):
+ - Fully unwind the stack for TerminatedExecutionException.
+ (JSC::Interpreter::privateExecute):
+ - Check if we've been terminated at the same time we check if we've
+ timed out.
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ - Check if we've been terminated at the same time we check if we've
+ timed out.
+ * runtime/Completion.cpp:
+ - Some exceptions define special completion types so that calls can
+ see why we terminated evaluation.
+ (JSC::evaluate):
+ * runtime/Completion.h:
+ - Define a new completion type for termination.
+ (JSC::):
+ * runtime/ExceptionHelpers.cpp:
+ - Define TerminatedExecutionException and refactor pseudo-RTTI
+ virtual function to be more semantic.
+ (JSC::InterruptedExecutionError::exceptionType):
+ (JSC::TerminatedExecutionError::TerminatedExecutionError):
+ (JSC::TerminatedExecutionError::exceptionType):
+ (JSC::TerminatedExecutionError::toString):
+ (JSC::createTerminatedExecutionException):
+ * runtime/ExceptionHelpers.h:
+ - Entry point for generating a TerminatedExecutionException.
+ * runtime/JSGlobalData.cpp:
+ (JSC::JSGlobalData::JSGlobalData):
+ - Add a Terminator object that can be used to asynchronously
+ terminate a JavaScript execution stack.
+ * runtime/JSGlobalData.h:
+ * runtime/JSObject.h:
+ (JSC::JSObject::exceptionType):
+ - Define that, by default, thrown objects have a normal exception
+ type.
+ * runtime/Terminator.h: Added.
+ - Added a new controller object that can be used to terminate
+ execution asynchronously. This object is more or less a
+ glorified bool.
+ (JSC::Terminator::Terminator):
+ (JSC::Terminator::termianteSoon):
+ (JSC::Terminator::shouldTerminate):
+
+2010-04-05 Oliver Hunt <oliver@apple.com>
+
+ And another one.
+
+ * JavaScriptCore.vcproj/jsc/jscCommon.vsprops:
+
+2010-04-05 Oliver Hunt <oliver@apple.com>
+
+ And another build fix.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
+
+2010-04-05 Oliver Hunt <oliver@apple.com>
+
+ Build fix
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2010-04-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Support weak maps in JSC
+ https://bugs.webkit.org/show_bug.cgi?id=37132
+
+ Expose an API to allow creation of a map for storing
+ weak JS references.
+
+ * API/JSWeakObjectMapRefInternal.h: Added.
+ (OpaqueJSWeakObjectMap::create):
+ (OpaqueJSWeakObjectMap::map):
+ (OpaqueJSWeakObjectMap::~OpaqueJSWeakObjectMap):
+ (OpaqueJSWeakObjectMap::OpaqueJSWeakObjectMap):
+ * API/JSWeakObjectMapRefPrivate.cpp: Added.
+ * API/JSWeakObjectMapRefPrivate.h: Added.
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::registerWeakMap):
+ (JSC::JSGlobalObject::deregisterWeakMap):
+
+2010-04-05 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Symbian] Consolidate Symbian WINSCW environment configuration
+ https://bugs.webkit.org/show_bug.cgi?id=37100
+
+ Move the "undefinition" of WIN32 and _WIN32 from WebCore/config.h
+ to JavaScriptCore/wtf/Platform.h as it is not specific to WebCore.
+
+ PLATFORM(WIN) and OS(WIN) no longer needs to be undefined as
+ undefining WIN32 takes care of it.
+
+ * wtf/Platform.h:
+
+2010-04-03 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=37068
+ Change UString to use a 0 rep for null strings instead of a null object.
+
+ No performance impact.
+
+ * JavaScriptCore.exp:
+ * runtime/InternalFunction.cpp:
+ (JSC::InternalFunction::InternalFunction):
+ * runtime/JSString.h:
+ (JSC::RopeBuilder::JSString):
+ * runtime/UString.cpp:
+ (JSC::initializeUString):
+ * runtime/UString.h:
+ (JSC::UString::UString):
+ (JSC::UString::data):
+ (JSC::UString::size):
+ (JSC::UString::isNull):
+ (JSC::UString::isEmpty):
+ (JSC::UString::cost):
+
+2010-04-03 Balazs Kelemen <kb@inf.u-szeged.hu>
+
+ Reviewed by Oliver Hunt.
+
+ Fix uninitalised members in CallLinkInfo and BytecodeGenerator.
+
+ https://bugs.webkit.org/show_bug.cgi?id=36816
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * bytecode/CodeBlock.h:
+ (JSC::CallLinkInfo::CallLinkInfo):
+
+2010-04-03 yael aharon <yael.aharon@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ Enable HTMLProgressElement for Safari on OSX
+ https://bugs.webkit.org/show_bug.cgi?id=36961
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-04-02 Ruben Van Boxem <vanboxem.ruben@gmail.com>
+
+ Reviewed by Eric Seidel.
+
+ Mingw-w64 fixes for JavaScriptCore
+ https://bugs.webkit.org/show_bug.cgi?id=35607
+
+ * runtime/Collector.cpp: use the msvc code for mingw-w64 (but not mingw-w32)
+ (JSC::Heap::allocateBlock):
+ (JSC::Heap::freeBlockPtr):
+ (JSC::currentThreadStackBase):
+ (JSC::currentThreadStackBase):
+ * wtf/Platform.h: added COMPILER(MINGW64) check to differentiate between mingw.org and mingw-w64 functions
+
+2010-04-02 Geoffrey Garen <ggaren@apple.com>
+
+ Build fix: updated the .def file.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-04-02 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Inlined toThisString and toThisJSString to avoid virtual function call overhead
+ https://bugs.webkit.org/show_bug.cgi?id=37039
+
+ Maybe a 1% speedup on iBench JS.
+
+ * JavaScriptCore.exp: New exports.
+
+ * runtime/JSCell.cpp:
+ * runtime/JSCell.h:
+ * runtime/JSNumberCell.cpp:
+ * runtime/JSNumberCell.h:
+ * runtime/JSString.cpp:
+ * runtime/JSString.h:
+ * runtime/JSValue.h:
+ * runtime/JSZombie.h:
+ (JSC::JSZombie::toThisObject): Nixed the old virtual-type implementation.
+
+ * runtime/JSObject.h:
+ (JSC::JSValue::toThisString):
+ (JSC::JSValue::toThisJSString): Added the inlined implementation.
+
+2010-04-02 Jeremy Moskovich <jeremy@chromium.org>
+
+ Reviewed by Geoffrey Garen.
+
+ Beef up documentation for ASSERT* and CRASH macros a bit.
+
+ https://bugs.webkit.org/show_bug.cgi?id=36527
+
+ * wtf/Assertions.h:
+
+2010-04-02 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Unreviewed, minor build fix.
+
+ Change the order of the member initialisation list
+ in constructor to match declaration order
+
+ * runtime/Collector.cpp:
+ (JSC::Heap::Heap):
+
+2010-04-01 Kinuko Yasuda <kinuko@chromium.org>
+
+ Reviewed by Dmitry Titov.
+
+ Add FileThread for async file operation support in FileReader and FileWriter
+ https://bugs.webkit.org/show_bug.cgi?id=36896
+
+ Add ENABLE_FILE_READER and ENABLE_FILE_WRITER flags.
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-03-31 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix pt II).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-31 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-31 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 36871 - Remove JSC::CString
+ Use WTF::CString instead (which until recently was WebCore::CString).
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * runtime/UString.cpp:
+ * runtime/UString.h:
+
+2010-03-31 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Unreviewed, fix after r56842.
+
+ Add UNUSED_PARAM a to silence warning.
+
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+
+2010-03-31 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Unreviewed, Symbian build fix.
+
+ Refactor JITStubs.cpp so that the list of STUB_FUNCTIONs
+ are not dependent on the JSVALUE32_64 guard.
+
+ * jit/JITStubs.cpp: Place the JSVALUE32_64 guard inside
+ the body of cti_op_eq_strings.
+ * jit/JITStubs.h: Remove JSVALUE32_64 guard from
+ cti_op_eq_strings stub.
+
+2010-03-30 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix).
+
+ Fixing b0rked version of JavaScriptCore.vcproj - added lines were truncated.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+
+2010-03-30 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=36866
+ Move CString to WTF
+
+ * Android.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.exp:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pro:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/WTF/WTF.vcproj:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * wtf/text: Added.
+ * wtf/text/CString.cpp: Copied from WebCore/platform/text/CString.cpp.
+ * wtf/text/CString.h: Copied from WebCore/platform/text/CString.h.
+ (WTF::CStringBuffer::data):
+ (WTF::CStringBuffer::length):
+ (WTF::CStringBuffer::create):
+ (WTF::CStringBuffer::CStringBuffer):
+ (WTF::CStringBuffer::mutableData):
+ (WTF::CString::CString):
+ (WTF::CString::isNull):
+ (WTF::CString::buffer):
+ (WTF::operator!=):
+
+2010-03-30 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by nobody, build break.
+
+ [Qt] Fix build break on Qt Mac.
+
+ DESTDIR path on Mac do not include the configuration path by default
+ like on Windows. Have to force it.
+
+ * JavaScriptCore.pro:
+
+2010-03-29 Alice Liu <alice.liu@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make:
+ add JSObjectRefPrivate.h
+
+2010-03-29 Chao-ying Fu <fu@mips.com>
+
+ Reviewed by Oliver Hunt.
+
+ MIPS JIT Supports
+ https://bugs.webkit.org/show_bug.cgi?id=30144
+
+ The following changes enable MIPS JIT.
+
+ * assembler/MIPSAssembler.h:
+ (JSC::MIPSAssembler::lbu):
+ (JSC::MIPSAssembler::linkWithOffset):
+ * assembler/MacroAssemblerMIPS.h:
+ (JSC::MacroAssemblerMIPS::load8):
+ (JSC::MacroAssemblerMIPS::branch8):
+ (JSC::MacroAssemblerMIPS::branchTest8):
+ (JSC::MacroAssemblerMIPS::setTest8):
+ (JSC::MacroAssemblerMIPS::setTest32):
+ * jit/JIT.h:
+ * jit/JITInlineMethods.h:
+ (JSC::JIT::preserveReturnAddressAfterCall):
+ (JSC::JIT::restoreReturnAddressBeforeReturn):
+ * jit/JITOpcodes.cpp:
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::JITThunks):
+ * jit/JITStubs.h:
+ (JSC::JITStackFrame::returnAddressSlot):
+ * wtf/Platform.h:
+
+2010-02-26 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Add support for Widgets 1.0: View Mode Media Feature
+ https://bugs.webkit.org/show_bug.cgi?id=35446
+
+ Add an enable flag for the Widgets (http://www.w3.org/TR/widgets-reqs/)
+ and turn it on for Qt only.
+
+ * wtf/Platform.h:
+
+2010-03-29 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Darin Adler.
+
+ Corrected name of (u)int64_t compile time assert.
+ https://bugs.webkit.org/show_bug.cgi?id=36739
+
+ int64_t_is_four_bytes -> int64_t_is_eight_bytes
+
+ * os-win32/stdint.h:
+
+2010-03-29 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Use the -l syntax for linking against JavaScriptCore on Windows.
+ This allow qmake to extract dependencies correctly when generating VS
+ solutions.
+
+ * JavaScriptCore.pri:
+
+2010-03-29 Thomas Zander <t.zander@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ https://bugs.webkit.org/show_bug.cgi?id=36742
+
+ gcc for Symbian doesn't support gcc extensions like atomicity.h - disable
+
+ * wtf/Threading.h: also detect os symbian
+
+2010-03-28 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Remove the definition of WTF_CHANGES guards from the build system
+ https://bugs.webkit.org/show_bug.cgi?id=31670
+
+ * JavaScriptCore.pro: Remove the definition of WTF_CHANGES
+ as it is already defined in config.h
+
+2010-03-28 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Add API for reporting additional memory cost of JavaScript objects
+ https://bugs.webkit.org/show_bug.cgi?id=36650
+
+ * qt/api/qscriptengine.cpp:
+ (QScriptEngine::reportAdditionalMemoryCost):
+ * qt/api/qscriptengine.h:
+ * qt/api/qscriptengine_p.h:
+ (QScriptEnginePrivate::reportAdditionalMemoryCost):
+ * qt/tests/qscriptengine/tst_qscriptengine.cpp:
+ (tst_QScriptEngine::reportAdditionalMemoryCost):
+
+2010-03-28 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ QScriptEngine API was enriched by globalObject() method
+ which give an access to the global object.
+
+ [Qt] QScriptEngine doesn't give an access to global object
+ https://bugs.webkit.org/show_bug.cgi?id=36603
+
+ * qt/api/qscriptengine.cpp:
+ (QScriptEngine::globalObject):
+ * qt/api/qscriptengine.h:
+ * qt/api/qscriptengine_p.cpp:
+ (QScriptEnginePrivate::globalObject):
+ * qt/api/qscriptengine_p.h:
+ * qt/tests/qscriptengine/tst_qscriptengine.cpp:
+ (tst_QScriptEngine::globalObject):
+
+2010-03-26 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Build JavaScriptCore as a static library.
+ https://bugs.webkit.org/show_bug.cgi?id=36590
+
+ This patch takes what was left of the unused JavaScriptCore.pro
+ and moved the compilation logic from JavaScriptCore.pri to
+ JavaScriptCore.pro.
+
+ * JavaScriptCore.pri:
+ * JavaScriptCore.pro:
+ * jsc.pro:
+ * qt/api/QtScript.pro:
+
+2010-03-25 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ * profiler/ProfileGenerator.cpp:
+ (JSC::ProfileGenerator::willExecute):
+ (JSC::ProfileGenerator::didExecute):
+
+2010-03-25 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Bug 36611 - Cleanup JSC::CString
+ Rename CString::c_str() -> CString::data(), CString::size() -> CString::length(),
+ remove UString::getCString() (all uses are wrong, should use UString::UTF8String()).
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::printUnaryOp):
+ (JSC::CodeBlock::printBinaryOp):
+ (JSC::CodeBlock::printConditionalJump):
+ (JSC::CodeBlock::printGetByIdOp):
+ (JSC::CodeBlock::printPutByIdOp):
+ (JSC::printGlobalResolveInfo):
+ (JSC::printStructureStubInfo):
+ (JSC::CodeBlock::printStructure):
+ (JSC::CodeBlock::printStructures):
+ (JSC::CodeBlock::dump):
+ * jsc.cpp:
+ (functionPrint):
+ (functionDebug):
+ (runInteractive):
+ (fillBufferWithContentsOfFile):
+ * profiler/CallIdentifier.h:
+ (JSC::CallIdentifier::c_str):
+ * profiler/Profile.cpp:
+ (JSC::Profile::debugPrintDataSampleStyle):
+ * profiler/ProfileNode.cpp:
+ (JSC::ProfileNode::debugPrintData):
+ (JSC::ProfileNode::debugPrintDataSampleStyle):
+ * runtime/DateConversion.cpp:
+ (JSC::parseDate):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode):
+ (JSC::globalFuncJSCPrint):
+ * runtime/UString.cpp:
+ (JSC::operator==):
+ (JSC::UString::toDouble):
+ * runtime/UString.h:
+ (JSC::CString::length):
+ (JSC::CString::data):
+
+2010-03-25 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by nobody, build fix.
+
+ [Qt] Build fix on MSVC. Reverts r55633 for stdint.h
+
+ This file gets included in generated moc files which don't
+ include the prefix header.
+
+ * os-win32/stdint.h:
+
+2010-03-24 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (windows build fix).
+
+2010-03-24 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Switch String::latin1, String::utf8, String::fromUTF8 to
+ use WTF's Unicode conversion methods rather than TextEncoder.
+ These methods only perform simple conversion, and don't need
+ really require TextEncoder's full capability (to look up arbitrary
+ encodings by name), switching to only be dependent on WTF will
+ make it easier if we chose to move WebCore::String to WTF.
+
+ * JavaScriptCore.exp:
+
+2010-03-24 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ * wtf/FastMalloc.h: Added a using directive for fastMallocSize, like we do for all public
+ WTF symbols. Also sorted the list alphabetically.
+
+2010-03-23 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (speculative windows build fix part II).
+
+2010-03-23 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (speculative windows build fix).
+
+2010-03-23 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 36519 - JSGlobalContextRelease is unnecessarily slow
+
+ Since [ http://trac.webkit.org/changeset/35917 ], calling
+ JSGlobalContextRelease always triggers a GC heap collection
+ (if not a full destroy). As per 35917's changelog "This is
+ only really necessary when the (JSGlobalObject's) last
+ reference is released, but there is no way to determine that,
+ and no harm in collecting slightly more often."
+
+ Well, we now know of cases of API clients who are harmed by
+ the performance penalty of collecting too often, so it's time
+ to add a way to determine whether a call to JSGlobalContextRelease
+ is removing the last protect from it's global object. If further
+ protects are retaining the global object (likely from other
+ JSGlobalContextRefs), then don't trigger a GC collection.
+
+ * API/JSContextRef.cpp:
+ * runtime/Collector.cpp:
+ (JSC::Heap::unprotect): return a boolean indicating that the value is now unprotected.
+ * runtime/Collector.h:
+ * wtf/HashCountedSet.h:
+ (WTF::::remove): return a boolean indicating whether the value was removed from the set.
+
+2010-03-23 Mark Rowe <mrowe@apple.com>
+
+ Build fix.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncSplice): Some versions of GCC emit a warning about the implicit 64- to 32-bit truncation
+ that takes place here. An explicit cast is sufficient to silence it.
+
+2010-03-23 Alexey Proskuryakov <ap@apple.com>
+
+ Build fix.
+
+ * runtime/ArrayPrototype.cpp: (JSC::arrayProtoFuncSplice): Fixed a typo - length doesn't
+ need to be converted with toInteger().
+
+2010-03-23 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ https://bugs.webkit.org/show_bug.cgi?id=36511
+ <rdar://problem/7753498> Safari freezes when using SPUTNIK JavaScript conformance check
+
+ Test: fast/js/sputnik-S15.4.4.12_A3_T3.html
+
+ * runtime/ArrayPrototype.cpp: (JSC::arrayProtoFuncSplice): We were incorrectly computing
+ the start offset, and iterated over (almost) all integers. Note that this can be fixed
+ without using doubles, but the code would be much more complicated, and there is no important
+ reason to stick to integers here.
+
+2010-03-23 Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ Fix compilation on Itanium in 32-bit mode
+ https://bugs.webkit.org/show_bug.cgi?id=36494
+
+ * wtf/Platform.h: Introduce CPU(IA64_32). Don't define
+ WTF_USE_JSVALUE64 if the CPU is in 32-bit mode.
+
+2010-03-23 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Interpreter fix for <rdar://problem/7728196> REGRESSION (r46701): -(-2147483648)
+ evaluates to -2147483648 on 32 bit (35842)
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute): Only take the fast negate path if
+ a bit other than bit 31 is set. If none of bits 0-30 are set, then the
+ value we're negating can only be 0 or -2147483648, and neither can be
+ negated in int space.
+
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_negate):
+ (JSC::JIT::emitSlow_op_negate): Updated the JIT implementation to match
+ the interpreter, since it's slightly simpler.
+
+2010-03-22 Siddharth Mathur <siddharth.mathur@nokia.com>
+
+ Reviewed by Laszlo Gombos.
+
+ [Symbian] More efficient aligned memory allocation for JSC Collector
+ https://bugs.webkit.org/show_bug.cgi?id=34350
+
+ * JavaScriptCore.pri: Added 2 new Symbian source files and HAL linkage
+
+ * runtime/Collector.cpp: Reduced port-specific code and added private data member
+ (JSC::Heap::Heap):
+ (JSC::Heap::~Heap):
+ (JSC::Heap::destroy):
+ (JSC::Heap::allocateBlock):
+ (JSC::Heap::freeBlockPtr):
+
+ * runtime/Collector.h: Added private data member
+
+ * wtf/symbian: Added.
+ * wtf/symbian/BlockAllocatorSymbian.cpp: Added.
+ (WTF::AlignedBlockAllocator::AlignedBlockAllocator): Helper class to allocate
+ aligned blocks more efficiently as required by Collector
+ (WTF::AlignedBlockAllocator::alloc):
+ (WTF::AlignedBlockAllocator::free):
+ (WTF::AlignedBlockAllocator::destroy):
+ (WTF::AlignedBlockAllocator::~AlignedBlockAllocator):
+ * wtf/symbian/BlockAllocatorSymbian.h: Added.
+
+2010-03-22 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed <rdar://problem/7728196> REGRESSION (r46701): -(-2147483648)
+ evaluates to -2147483648 on 32 bit (35842)
+
+ Two ways to fix the same bug:
+
+ 1. Check for overflow when negating, since negating the largest negative
+ int causes overflow.
+
+ 2. Constant-fold even when negating a negative, since, like they say in
+ high school, "math works."
+
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::branchNeg32):
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::branchNeg32): Added a branching version
+ of the negate operator.
+
+ * jit/JITArithmetic.cpp:
+ (JSC::JIT::emit_op_negate): Use the branching version of the negate
+ operator to check for overflow.
+
+ (JSC::JIT::emitSlow_op_negate): Link the check for overflow to a slow case.
+ (We could emit inline code for this, since we know what the result would
+ be, but that's probably just a waste of generated code.)
+
+ * parser/Grammar.y: Constant fold even when negating a negative.
+
+2010-03-22 David Kilzer <ddkilzer@apple.com>
+
+ <http://webkit.org/b/36431> Clean up 'int' use in UString.cpp after r54789
+
+ Reviewed by Darin Adler.
+
+ * runtime/UString.cpp:
+ (JSC::UString::from): Changed argument type from 'unsigned int'
+ to 'unsigned' to match WebKit coding style.
+ (JSC::UString::find): Changed static_cast<int>() to
+ static_cast<unsigned>() now that this method returns unsigned.
+ (JSC::UString::rfind): Ditto.
+ * runtime/UString.h:
+ (JSC::UString::from): Changed argument type from 'unsigned int'
+ to 'unsigned' to match WebKit coding style.
+
+2010-03-22 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Add support for syntax checking in the QtScript API.
+
+ New class was created; the QScriptSyntaxCheckResult which main
+ responsibility is to provide results of the ECMA Script code
+ syntax check. The class is not fully functional as the JSC C API
+ doesn't expose an error column number, but it is a good start point
+ for a future development.
+
+ [Qt] QtScript functionality should be extended by syntax checking.
+ https://bugs.webkit.org/show_bug.cgi?id=36123
+
+ * qt/api/QtScript.pro:
+ * qt/api/qscriptengine.cpp:
+ (QScriptEngine::checkSyntax):
+ * qt/api/qscriptengine.h:
+ * qt/api/qscriptengine_p.cpp:
+ (QScriptEnginePrivate::checkSyntax):
+ * qt/api/qscriptengine_p.h:
+ * qt/api/qscriptsyntaxcheckresult.cpp: Added.
+ (QScriptSyntaxCheckResult::QScriptSyntaxCheckResult):
+ (QScriptSyntaxCheckResult::~QScriptSyntaxCheckResult):
+ (QScriptSyntaxCheckResult::operator=):
+ (QScriptSyntaxCheckResult::state):
+ (QScriptSyntaxCheckResult::errorLineNumber):
+ (QScriptSyntaxCheckResult::errorColumnNumber):
+ (QScriptSyntaxCheckResult::errorMessage):
+ * qt/api/qscriptsyntaxcheckresult.h: Added.
+ * qt/api/qscriptsyntaxcheckresult_p.cpp: Added.
+ (QScriptSyntaxCheckResultPrivate::~QScriptSyntaxCheckResultPrivate):
+ (QScriptSyntaxCheckResultPrivate::errorMessage):
+ (QScriptSyntaxCheckResultPrivate::errorLineNumber):
+ * qt/api/qscriptsyntaxcheckresult_p.h: Added.
+ (QScriptSyntaxCheckResultPrivate::get):
+ (QScriptSyntaxCheckResultPrivate::QScriptSyntaxCheckResultPrivate):
+ (QScriptSyntaxCheckResultPrivate::state):
+ (QScriptSyntaxCheckResultPrivate::errorColumnNumber):
+ * qt/tests/qscriptengine/tst_qscriptengine.cpp:
+ (tst_QScriptEngine::checkSyntax_data):
+ (tst_QScriptEngine::checkSyntax):
+
+2010-03-21 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ New class; QScriptProgram.
+
+ The class should be used to evaluate the same script multiple times
+ more efficiently.
+
+ [Qt] QtScript should have QScriptProgram class
+ https://bugs.webkit.org/show_bug.cgi?id=36008
+
+ * qt/api/QtScript.pro:
+ * qt/api/qscriptengine.cpp:
+ (QScriptEngine::evaluate):
+ * qt/api/qscriptengine.h:
+ * qt/api/qscriptengine_p.cpp:
+ (QScriptEnginePrivate::evaluate):
+ * qt/api/qscriptengine_p.h:
+ (QScriptEnginePrivate::evaluate):
+ * qt/api/qscriptprogram.cpp: Added.
+ (QScriptProgram::QScriptProgram):
+ (QScriptProgram::~QScriptProgram):
+ (QScriptProgram::operator=):
+ (QScriptProgram::isNull):
+ (QScriptProgram::sourceCode):
+ (QScriptProgram::fileName):
+ (QScriptProgram::firstLineNumber):
+ (QScriptProgram::operator==):
+ (QScriptProgram::operator!=):
+ * qt/api/qscriptprogram.h: Added.
+ * qt/api/qscriptprogram_p.h: Added.
+ (QScriptProgramPrivate::get):
+ (QScriptProgramPrivate::QScriptProgramPrivate):
+ (QScriptProgramPrivate::~QScriptProgramPrivate):
+ (QScriptProgramPrivate::isNull):
+ (QScriptProgramPrivate::sourceCode):
+ (QScriptProgramPrivate::fileName):
+ (QScriptProgramPrivate::firstLineNumber):
+ (QScriptProgramPrivate::operator==):
+ (QScriptProgramPrivate::operator!=):
+ (QScriptProgramPrivate::program):
+ (QScriptProgramPrivate::file):
+ (QScriptProgramPrivate::line):
+ * qt/tests/qscriptengine/tst_qscriptengine.cpp:
+ (tst_QScriptEngine::evaluateProgram):
+
+2010-03-21 David Kilzer <ddkilzer@apple.com>
+
+ Blind attempt #2 to fix the Windows build after r56314
+
+ * API/tests/testapi.c: Include JSObjectRefPrivate.h for the new
+ methods instead of declaring them locally (and non-extern).
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+ Backed out previous change.
+
+2010-03-21 David Kilzer <ddkilzer@apple.com>
+
+ Blind attempt to fix the Windows build after r56314
+
+ Try to fix the following errors on the Windows buildbot:
+
+ Linking...
+ testapi.obj : error LNK2001: unresolved external symbol "bool __cdecl JSObjectSetPrivateProperty(struct OpaqueJSContext const *,struct OpaqueJSValue *,struct OpaqueJSString *,struct OpaqueJSValue const *)" (?JSObjectSetPrivateProperty@@YA_NPBUOpaqueJSContext@@PAUOpaqueJSValue@@PAUOpaqueJSString@@PBU2@@Z)
+ testapi.obj : error LNK2001: unresolved external symbol "struct OpaqueJSValue const * __cdecl JSObjectGetPrivateProperty(struct OpaqueJSContext const *,struct OpaqueJSValue *,struct OpaqueJSString *)" (?JSObjectGetPrivateProperty@@YAPBUOpaqueJSValue@@PBUOpaqueJSContext@@PAU1@PAUOpaqueJSString@@@Z)
+ C:\cygwin\home\buildbot\slave\win-release\build\WebKitBuild\bin\testapi.exe : fatal error LNK1120: 2 unresolved externals
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def: Added
+ missing symbols to be exported.
+
+2010-03-21 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Documentation fix for previous patch.
+
+ * API/JSObjectRefPrivate.h:
+
+2010-03-20 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ JSC needs an API to allow custom objects to have aprivate GC-accessible properties
+ https://bugs.webkit.org/show_bug.cgi?id=36420
+
+ Add new API methods to support "private" properties on custom
+ objects.
+
+ * API/JSCallbackObject.h:
+ (JSC::JSCallbackObjectData::JSCallbackObjectData):
+ (JSC::JSCallbackObjectData::~JSCallbackObjectData):
+ (JSC::JSCallbackObjectData::getPrivateProperty):
+ (JSC::JSCallbackObjectData::setPrivateProperty):
+ (JSC::JSCallbackObjectData::deletePrivateProperty):
+ (JSC::JSCallbackObjectData::markChildren):
+ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::getPrivateProperty):
+ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::setPrivateProperty):
+ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::deletePrivateProperty):
+ (JSC::JSCallbackObjectData::JSPrivatePropertyMap::markChildren):
+ (JSC::JSCallbackObject::getPrivateProperty):
+ (JSC::JSCallbackObject::setPrivateProperty):
+ (JSC::JSCallbackObject::deletePrivateProperty):
+ (JSC::JSCallbackObject::markChildren):
+ * API/JSObjectRef.cpp:
+ (JSObjectGetPrivateProperty):
+ (JSObjectSetPrivateProperty):
+ (JSObjectDeletePrivateProperty):
+ * API/JSObjectRefPrivate.h: Added.
+ * API/tests/testapi.c:
+ (main):
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2010-03-20 Kevin Ollivier <kevino@theolliviers.com>
+
+ [wx] Build fixes after introduction of Brew files.
+
+ * wscript:
+
+2010-03-18 Tom Callaway <tcallawa@redhat.com>
+
+ Reviewed by Darin Adler.
+
+ Bug 35429: Fix compile on SPARC64
+ https://bugs.webkit.org/show_bug.cgi?id=35429
+
+ * wtf/Platform.h: Set WTF_USE_JSVALUE64 for SPARC64
+
+2010-03-18 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Add API to directly expose JSON parsing
+ https://bugs.webkit.org/show_bug.cgi?id=34887
+
+ Add API to expose JSON parsing directly, and add tests to testapi
+
+ * API/JSValueRef.cpp:
+ (JSValueMakeFromJSONString):
+ (JSValueCreateJSONString):
+ * API/tests/testapi.c:
+ (main):
+ * JavaScriptCore.exp:
+ * runtime/JSONObject.cpp:
+ (JSC::JSONStringify):
+ * runtime/JSONObject.h:
+
+2010-03-16 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Darin Adler and Mark Rowe.
+
+ Update WebKit availability macros for release after 4.0.
+
+ * API/WebKitAvailability.h:
+
+2010-03-17 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ undefined, NaN, and Infinity should be ReadOnly
+ https://bugs.webkit.org/show_bug.cgi?id=36263
+
+ Simply add the ReadOnly flag to these properties.
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+
+2010-03-17 Darin Adler <darin@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Speed up Math.round a little by removing unneeded special case
+ https://bugs.webkit.org/show_bug.cgi?id=36107
+
+ Test: fast/js/math.html
+
+ * runtime/MathObject.cpp:
+ (JSC::mathProtoFuncRound): This function had a special case for numbers
+ between -0.5 and -0.0 to return -0.0. But the algorithm in the function
+ already yields -0.0 for those cases, so the extra checking and branching
+ is unneeded.
+
+2010-03-17 Mike Homey <glandium@debian.org>
+
+ Reviewed by Gustavo Noronha.
+
+ Build fix for SPARC. Fix missing macro value.
+
+ * wtf/Platform.h:
+
+2010-03-16 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt, Darin Adler.
+
+ Bug 36083 - REGRESSION (r55772-r55834): Crash in JavaScriptCore RegExp code on PowerPC
+
+ The problem is a bug in our port of PCRE - that a read may take place from the first character in an
+ empty string. For the time being, revert to using a valid pointer in the data segment rather than
+ an invalid non-null pointer into the zero-page for the empty string's data pointer. A better fix for
+ this will be to remove PCRE.
+
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::empty):
+
+2010-03-16 Darin Adler <darin@apple.com>
+
+ Rolled out r56081 since it broke the Windows build.
+
+2010-03-16 Zoltan Horvath <zoltan@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Remove extra <new> include and add guards to operator new/delete definitions
+ https://bugs.webkit.org/show_bug.cgi?id=35967
+
+ Remove extra <new> header include from FastAlloc.cpp since it is included in
+ FastAlloc.h. Add ENABLE(GLOBAL_FASTMALLOC_NEW) macro guard to operator
+ new/delete/new []/delete [] definitions.
+
+ * wtf/FastMalloc.cpp:
+
+2010-03-15 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Eric Seidel.
+
+ [BREWMP] Add a function to create a BREW instance without local variable declarations.
+ https://bugs.webkit.org/show_bug.cgi?id=34705
+
+ Add a template function to create a BREW instance in one line.
+
+ * wtf/brew/ShellBrew.h: Added.
+ (WTF::createInstance):
+
+2010-03-15 Geoffrey Garen <ggaren@apple.com>
+
+ Not reviewed.
+
+ Removed a now-incorrect comment I forgot to remove in my last check-in.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_PageHeap::scavenge):
+
+2010-03-15 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ Fixed a portion of:
+ <rdar://problem/7165917> | https://bugs.webkit.org/show_bug.cgi?id=28676
+ Safari 4 does not release memory back to the operating system fast enough (28676)
+
+ Every few seconds, release a percentage of the minimum unused page count
+ during that time period.
+
+ SunSpider reports no change, command-line or in-browser, Mac or Windows.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::TCMalloc_PageHeap::init):
+ (WTF::TCMalloc_PageHeap::signalScavenger):
+ (WTF::TCMalloc_PageHeap::initializeScavenger): Renamed shouldContinueScavenging
+ to shouldScavenge, since scavenging is no longer something that we interrupt.
+
+ (WTF::TCMalloc_PageHeap::scavenge): The new scavenging algorithm. Fixes
+ a bug where the old code would release only one item from each size class
+ per scavenge, potentially leaving large numbers of large-sized objects
+ unreleased for a long time.
+
+ (WTF::TCMalloc_PageHeap::shouldScavenge):
+ (WTF::TCMalloc_PageHeap::New):
+ (WTF::TCMalloc_PageHeap::AllocLarge):
+ (WTF::TCMalloc_PageHeap::Delete):
+ (WTF::TCMalloc_PageHeap::GrowHeap):
+ (WTF::TCMalloc_PageHeap::scavengerThread):
+ (WTF::TCMalloc_PageHeap::periodicScavenge): Updated to track the minimum
+ value of free_committed_pages_ during a given scavenge period.
+
+2010-03-15 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=35843
+ Re-land reverted fix to JSString::getIndex()
+
+ Calling getIndex() on a JSString in rope form may result in a JSException being thrown
+ if there is insuficient memory so value(exec) returns UString() with length zero,
+ which will be passed to jsSingleCharacterSubstring.
+ Add a slow case function to trap the error & return a safe null value, until the
+ exception is handled.
+
+ * runtime/JSString.cpp:
+ (JSC::JSString::getIndexSlowCase):
+ (JSC::JSString::getStringPropertyDescriptor):
+ * runtime/JSString.h:
+ (JSC::jsSingleCharacterSubstring):
+ (JSC::JSString::getIndex):
+ (JSC::jsSingleCharacterString):
+ (JSC::JSString::getStringPropertySlot):
+
+2010-03-04 Kenneth Rohde Christiansen <kenneth@webkit.org>
+
+ Reviewed by Adam Roben.
+
+ Add a long long version of abs() for MSVC.
+
+ * wtf/MathExtras.h:
+ (abs):
+
+2010-03-15 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Combine ctiTrampolines on ARM and Thumb-2
+ https://bugs.webkit.org/show_bug.cgi?id=36014
+
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::JITThunks):
+
+2010-03-12 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-12 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-11 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 36075 - Clean up screwyness re static string impls & Identifiers.
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClass::~OpaqueJSClass): Classname may be null/empty, and these are an identifer. This is okay, since the null/empty strings are shared across all threads.
+ * JavaScriptCore.exp:
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add): No need to explicitly hash null reps, this is done in the ststic UStringImpl constructor.
+ (JSC::Identifier::addSlowCase): UStringImpl::empty() handled & checkCurrentIdentifierTable now called in the header.
+ (JSC::Identifier::checkCurrentIdentifierTable): Replaces checkSameIdentifierTable (this no longer checked the rep since the identifierTable pointer was removed from UString::Rep long ago).
+ * runtime/Identifier.h:
+ (JSC::Identifier::add): Replace call to checkSameIdentifierTable with call to checkCurrentIdentifierTable at head of function.
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::~UStringImpl): Remove call to checkConsistency - this function no longer checks anything interesting.
+ * runtime/UStringImpl.h:
+ (JSC::UStringOrRopeImpl::UStringOrRopeImpl): Set s_refCountFlagIsIdentifier in static constructor.
+ (JSC::UStringImpl::UStringImpl): remove calls to checkConsistency (see above), add new ASSERT to substring constructor.
+ (JSC::UStringImpl::setHash): ASSERT not static (static strings set the hash in their constructor, should not reach this code path).
+ (JSC::UStringImpl::create): Add missing ASSERT.
+ (JSC::UStringImpl::setIsIdentifier): ASSERT !isStatic() (static strings hash set in constructor).
+
+2010-03-12 Peter Varga <pvarga@inf.u-szeged.hu>
+
+ Reviewed by David Levin.
+
+ Two functions tryConsumeCharacter() and tryConsumeCharacterClass() are
+ removed from yarr/RegexInterpreter.cpp because they are never called.
+
+ * yarr/RegexInterpreter.cpp:
+
+2010-03-11 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ The JSNative state was renamed to JSPrimitive. The new name better
+ coresponds to the ECMAScript standard.
+
+ Enum QScriptValuePrivate::States was renamed to State to obey Qt
+ coding style rules ("States" name suggests that a state could
+ mixed together with an other state using bitwise logic operators.
+
+ [Qt] QScriptValuePrivate::States has naming issues
+ https://bugs.webkit.org/show_bug.cgi?id=35968
+
+ * qt/api/qscriptvalue_p.h:
+ (QScriptValuePrivate::):
+ (QScriptValuePrivate::QScriptValuePrivate):
+ (QScriptValuePrivate::isBool):
+ (QScriptValuePrivate::isNumber):
+ (QScriptValuePrivate::isNull):
+ (QScriptValuePrivate::isString):
+ (QScriptValuePrivate::isUndefined):
+ (QScriptValuePrivate::toString):
+ (QScriptValuePrivate::toNumber):
+ (QScriptValuePrivate::toBool):
+ (QScriptValuePrivate::assignEngine):
+ (QScriptValuePrivate::refinedJSValue):
+
+2010-03-11 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (Windows build fix).
+
+ Add export.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-11 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (Windows build fix).
+
+ Add export.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-11 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Oliver Hunt.
+
+ Remove nonsense comments used in development & commited in error.
+
+ * runtime/UStringImpl.h:
+
+2010-03-11 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (Windows build fix).
+
+ Remove export.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-11 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ https://bugs.webkit.org/show_bug.cgi?id=36041
+ Remove unnecessary differences in common code between WebCore::StringImpl & JSC::UStringImpl
+
+ Much of the code in WebCore::StringImpl and JSC::UStringImpl is now very similar,
+ but has trivial and unnecessary formatting differences, such as the exact wording
+ of comments, missing ASSERTs, functions implemented in the .h vs .cpp etc.
+
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add): UStringImpl::empty() now automatically hashes, uas per WebCore strings.
+ (JSC::Identifier::addSlowCase): UStringImpl::empty() now automatically hashes, uas per WebCore strings.
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::~UStringImpl): Only call bufferOwnership() once, add missing ASSERTs.
+ (JSC::UStringImpl::createUninitialized): Move from .h, not commonly called, no need to inline.
+ (JSC::UStringImpl::create): Move from .h, not commonly called, no need to inline.
+ (JSC::UStringImpl::sharedBuffer): Rewritten to more closely match WebCore implementation, remove need for separate baseSharedBuffer() method.
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::UStringImpl): Automatically hash static strings, ASSERT m_data & m_length are non-null/non-zero in non-static strings.
+ (JSC::UStringImpl::setHash): Add missing ASSERT.
+ (JSC::UStringImpl::create): Moved to .cpp / added missing check for empty string creation.
+ (JSC::UStringImpl::adopt): Vector.size() returns size_t, not unsigned.
+ (JSC::UStringImpl::cost): Renamed m_bufferSubstring -> m_substringBuffer
+ (JSC::UStringImpl::hash): Reordered in file.
+ (JSC::UStringImpl::existingHash): Reordered in file.
+ (JSC::UStringImpl::computeHash): Reordered in file, renamed parameter.
+ (JSC::UStringImpl::checkConsistency): rewrote ASSERT.
+ (JSC::UStringImpl::bufferOwnership): Return type should be BufferOwnership.
+ (JSC::UStringImpl::): Moved friends to head of class.
+
+2010-03-11 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by David Kilzer.
+
+ <rdar://problem/7745082> Make it possible to build WebKit for older Mac OS X versions from the current Mac OS X version
+
+ Default to using the appropriate SDK if the target Mac OS X version is not the current Mac OS X version.
+
+ * Configurations/Base.xcconfig:
+
+2010-03-11 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Tim Hatcher.
+
+ <rdar://problem/7745082> Make it possible to build WebKit for older Mac OS X versions from the current Mac OS X version
+
+ Introduce TARGET_MAC_OS_X_VERSION_MAJOR to represent the Mac OS X version that is being targeted. It defaults to the
+ current Mac OS X version unless otherwise specified.
+
+ Key off TARGET_MAC_OS_X_VERSION_MAJOR where we'd previously been keying off MAC_OS_X_VERSION_MAJOR.
+
+ Explicitly map from the target Mac OS X version to the preferred compiler since Xcode's default compiler choice
+ may not be usable when targetting a different Mac OS X version.
+
+ Key off TARGET_GCC_VERSION rather than MAC_OS_X_VERSION_MAJOR in locations where we'd previously been keying off
+ MAC_OS_X_VERSION_MAJOR but the decision is really related to the compiler version being used.
+
+ * Configurations/Base.xcconfig:
+ * Configurations/DebugRelease.xcconfig:
+ * Configurations/FeatureDefines.xcconfig:
+ * Configurations/JavaScriptCore.xcconfig:
+ * Configurations/Version.xcconfig:
+
+2010-03-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Sort the project file.
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2010-03-11 Simon Fraser <simon.fraser@apple.com>
+
+ Reviewed by Mark Rowe.
+
+ Sort the project file .
+
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+
+2010-03-11 Gabor Loki <loki@webkit.org>
+
+ Reviewed by Gavin Barraclough.
+
+ Buildfix for Thumb-2 after r55684. Add branch8 and branchTest8 functions.
+ https://bugs.webkit.org/show_bug.cgi?id=35892
+
+ * assembler/ARMv7Assembler.h:
+ (JSC::ARMv7Assembler::):
+ (JSC::ARMv7Assembler::ldrb):
+ * assembler/MacroAssemblerARMv7.h:
+ (JSC::MacroAssemblerARMv7::load8):
+ (JSC::MacroAssemblerARMv7::branch8):
+ (JSC::MacroAssemblerARMv7::branchTest8):
+ (JSC::MacroAssemblerARMv7::setTest8):
+
+2010-03-10 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber stamped by Oliver Hunt.
+
+ Rename JSC::UStringImpl::data() to characters(), to match WebCore::StringImpl.
+
+ * API/JSClassRef.cpp:
+ (OpaqueJSClassContextData::OpaqueJSClassContextData):
+ * bytecompiler/BytecodeGenerator.cpp:
+ (JSC::keyForCharacterSwitch):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::processClauseList):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+ * jit/JITStubs.cpp:
+ (JSC::DEFINE_STUB_FUNCTION):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncToString):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::equal):
+ (JSC::Identifier::addSlowCase):
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ * runtime/UString.cpp:
+ (JSC::UString::toStrictUInt32):
+ (JSC::equal):
+ * runtime/UString.h:
+ (JSC::UString::data):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::characters):
+ (JSC::UStringImpl::hash):
+ (JSC::UStringImpl::setHash):
+
+2010-03-10 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Darin Adler, Geoffrey Garen, Maciej Stachowiak.
+
+ https://bugs.webkit.org/show_bug.cgi?id=35991
+ Would be faster to not use a thread specific to implement StringImpl::empty()
+
+ Change JSC::UStringImpl's implementation of empty() match to match StringImpl's new implementation
+ (use a static defined within the empty() method), and change the interface to match too (return
+ a pointer not a reference).
+
+ ~0% performance impact (possible minor progression from moving empty() from .h to .cpp).
+
+ * JavaScriptCore.exp:
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add):
+ (JSC::Identifier::addSlowCase):
+ * runtime/PropertyNameArray.cpp:
+ (JSC::PropertyNameArray::add):
+ * runtime/UString.cpp:
+ (JSC::initializeUString):
+ (JSC::UString::UString):
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::empty):
+ (JSC::UStringImpl::create):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::adopt):
+ (JSC::UStringImpl::createUninitialized):
+ (JSC::UStringImpl::tryCreateUninitialized):
+
+2010-03-10 Dmitry Titov <dimich@chromium.org>
+
+ Not reviewed, fixing Snow Leopard build.
+
+ * wtf/mac/MainThreadMac.mm: Forgot 'static' for a new local function.
+ (WTF::postTimer):
+
+2010-03-10 Dmitry Titov <dimich@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Make Document::postTask to use a single queue of tasks, to fire them in order
+ https://bugs.webkit.org/show_bug.cgi?id=35943
+
+ The patch uses CFRunLoopTimer to schedule execution of tasks instead of performSelectorOnMainThread which apparently can starve other event sources.
+ The timer is used when the schedule request is coming on the main thread itself. This happens when the task is posted on the main thread or
+ when too many tasks are posted and the queue does 'stop and re-schedule' to make sure run loop has a chance to execute other events.
+
+ * wtf/mac/MainThreadMac.mm:
+ (WTF::timerFired):
+ (WTF::postTimer):
+ (WTF::scheduleDispatchFunctionsOnMainThread): Use timer posted to the current RunLoop if scheduling the task execution while on the main thread.
+
+2010-03-10 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: added new symbol.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-10 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: removed old symbol.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Alexey Proskuryakov, Darin Adler, and Sam Weinig.
+
+ Refactored fastCheckConsistency to match some review comments:
+ - renamed fastCheckConsistency to fastMallocSize, and changed ValueCheck
+ to ASSERT that a pointer's fastMallocSize is not 0.
+ - implemented a version of fastMallocSize for tcmalloc.
+
+ Also moved some pre-existing code around to avoid a problem related to
+ mismatched #define/#undef of malloc/free in this source file.
+
+ * JavaScriptCore.exp:
+ * wtf/FastMalloc.cpp:
+ (WTF::fastMallocSize): Renamed. Fixed indentation.
+
+ (WTF::TCMalloc_PageHeap::scavenge): Removed an incorrect ASSERT that
+ got in the way of testing the tcmalloc implementation. (More information
+ on why this ASSERT is incorrect is in <rdar://problem/7165917>.)
+
+ (WTF::TCMallocStats::fastMallocSize): Implemented for tcmalloc.
+
+ * wtf/FastMalloc.h: Updated for rename.
+
+ * wtf/ValueCheck.h:
+ (WTF::): Moved the ASSERT that used to be in fastCheckConsistency here.
+
+2010-03-10 Kevin Ollivier <kevino@theolliviers.com>
+
+ Reviewed by Eric Seidel.
+
+ Make global new/delete operators configurable for all ports and disable it
+ for the wx port for now.
+
+ * wtf/FastMalloc.h:
+ * wtf/Platform.h:
+
+2010-03-09 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (reverting r54510).
+
+ This caused a performance regression, by breaking the code
+ generator's logic to calculate the skip level for resolving
+ variables (traced by rdar:7683350) Reverting for now.
+
+ * parser/Grammar.y:
+ * parser/NodeConstructors.h:
+ (JSC::ContinueNode::ContinueNode):
+ (JSC::BreakNode::BreakNode):
+ (JSC::ForInNode::ForInNode):
+ * runtime/CommonIdentifiers.cpp:
+ (JSC::CommonIdentifiers::CommonIdentifiers):
+ * runtime/CommonIdentifiers.h:
+ * runtime/FunctionPrototype.cpp:
+ (JSC::FunctionPrototype::FunctionPrototype):
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::add):
+ * runtime/PropertyNameArray.cpp:
+ (JSC::PropertyNameArray::add):
+
+2010-03-09 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Darin Adler.
+
+ Changed FastMalloc statistics reporting to be a bit clearer. We now
+ report:
+ - Reserved VM Bytes: the VM that has been mapped into the process.
+ - Committed VM Bytes: the subset of Reserved VM Bytes actually in use.
+ - Free List Bytes: the subset of Committed VM Bytes in a free list.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::fastMallocStatistics):
+ (WTF::TCMallocStats::fastMallocStatistics): Updated to report the statistics
+ above. Standardized use of "ifdef WTF_CHANGES". Added a SpinLockHolder
+ around all statistics gathering, since it reads from the page heap.
+
+ * wtf/FastMalloc.h: Updated to report the statistics above.
+
+2010-03-09 Gabor Loki <loki@webkit.org>
+
+ Rubber-stamped by Maciej Stachowiak.
+
+ Buildfix for ARM after r55684. Add branch8 and branchTest8 functions.
+ https://bugs.webkit.org/show_bug.cgi?id=35892
+
+ * assembler/ARMAssembler.cpp:
+ (JSC::ARMAssembler::dataTransfer32):
+ * assembler/ARMAssembler.h:
+ (JSC::ARMAssembler::):
+ * assembler/MacroAssemblerARM.h:
+ (JSC::MacroAssemblerARM::load8):
+ (JSC::MacroAssemblerARM::branch8):
+ (JSC::MacroAssemblerARM::branchTest8):
+
+2010-03-08 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: 'P' is not a type. Luckily, 'void' is.
+
+ * wtf/FastMalloc.cpp:
+ (WTF::fastCheckConsistency):
+
+2010-03-08 Geoffrey Garen <ggaren@apple.com>
+
+ Windows build fix: export a new symbol.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-08 Geoffrey Garen <ggaren@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Switching malloc implementations requires a world rebuild
+ https://bugs.webkit.org/show_bug.cgi?id=35899
+
+ * wtf/FastMalloc.cpp:
+ (WTF::fastCheckConsistency):
+ (WTF::TCMallocStats::fastCheckConsistency):
+ * wtf/FastMalloc.h:
+ * wtf/ValueCheck.h:
+ (WTF::): Moved pointer checking into a helper function in FastMalloc.cpp,
+ so you can switch malloc implementations without rebuilding the world.
+
+2010-03-07 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Darin Adler.
+
+ TypeInfo is unnecessarily large
+ https://bugs.webkit.org/show_bug.cgi?id=35850
+
+ Reduce the size of the type and flags members to a single
+ byte each, reducing the size of Structure by 8 bytes.
+
+ * assembler/MacroAssemblerX86Common.h:
+ (JSC::MacroAssemblerX86Common::branch8):
+ (JSC::MacroAssemblerX86Common::branchTest8):
+ (JSC::MacroAssemblerX86Common::setTest8):
+ Add single byte branches, and correct setTest8 to do a
+ single byte read from memory, and actually store the result
+ * assembler/X86Assembler.h:
+ (JSC::X86Assembler::):
+ (JSC::X86Assembler::cmpb_im):
+ (JSC::X86Assembler::testb_im):
+ * jit/JITCall.cpp:
+ (JSC::JIT::emit_op_construct_verify):
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::emit_op_instanceof):
+ (JSC::JIT::emit_op_jeq_null):
+ (JSC::JIT::emit_op_jneq_null):
+ (JSC::JIT::emit_op_get_pnames):
+ (JSC::JIT::emit_op_convert_this):
+ (JSC::JIT::emit_op_construct_verify):
+ (JSC::JIT::emit_op_to_jsnumber):
+ (JSC::JIT::emit_op_eq_null):
+ (JSC::JIT::emit_op_neq_null):
+ * runtime/JSTypeInfo.h:
+ (JSC::TypeInfo::TypeInfo):
+ (JSC::TypeInfo::type):
+
+2010-03-08 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by NOBODY (reverting regression).
+
+ Reverting 55035, this caused a regression.
+ (https://bugs.webkit.org/show_bug.cgi?id=35843)
+
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ (JSC::JSString::getStringPropertyDescriptor):
+ * runtime/JSString.h:
+ (JSC::jsSingleCharacterSubstring):
+ (JSC::JSString::getIndex):
+ (JSC::JSString::getStringPropertySlot):
+ * runtime/UStringImpl.cpp:
+ * runtime/UStringImpl.h:
+
+2010-03-08 Stuart Morgan <stuartmorgan@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ Added a new USE definition for secure text mode on the Mac.
+ https://bugs.webkit.org/show_bug.cgi?id=31265
+
+ * wtf/Platform.h:
+
+2010-03-08 Jian Li <jianli@chromium.org>
+
+ Reviewed by Dmitry Titov.
+
+ Blob.slice support.
+ https://bugs.webkit.org/show_bug.cgi?id=32993
+
+ Add ENABLE_BLOB_SLICE feature define.
+ Also fix a problem that JSValue.toInteger is not exposed on Windows.
+
+ * Configurations/FeatureDefines.xcconfig:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-07 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Small performance fix in the QScriptConverter::toString().
+
+ The QByteArray was replaced by the QVarLengthArray which doesn't
+ have to allocate any memory on heap.
+
+ [Qt] QScriptConverter::toString() should use QVarLengthArray instead of QByteArray
+ https://bugs.webkit.org/show_bug.cgi?id=35577
+
+ * qt/api/qscriptconverter_p.h:
+ (QScriptConverter::toString):
+
+2010-03-06 Mark Rowe <mrowe@apple.com>
+
+ Rubber-stamped by Sam Weinig.
+
+ Remove unnecessary includes of wtf/Platform.h. This is already pulled in by config.h.
+
+ * API/APICast.h:
+ * API/JSCallbackFunction.cpp:
+ * API/JSContextRef.cpp:
+ * API/JSObjectRef.cpp:
+ * API/JSValueRef.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:
+ * assembler/MacroAssembler.h:
+ * assembler/MacroAssemblerARM.h:
+ * assembler/MacroAssemblerARMv7.h:
+ * assembler/MacroAssemblerCodeRef.h:
+ * assembler/MacroAssemblerMIPS.h:
+ * assembler/MacroAssemblerX86.h:
+ * assembler/MacroAssemblerX86Common.h:
+ * assembler/MacroAssemblerX86_64.h:
+ * assembler/RepatchBuffer.h:
+ * assembler/X86Assembler.h:
+ * jit/JIT.h:
+ * jit/JITCode.h:
+ * jit/JITInlineMethods.h:
+ * jit/JITStubs.h:
+ * os-win32/stdint.h:
+ * runtime/JSAPIValueWrapper.h:
+ * runtime/JSImmediate.h:
+ * wtf/ASCIICType.h:
+ * wtf/StdLibExtras.h:
+ * wtf/VMTags.h:
+ * yarr/RegexCompiler.h:
+ * yarr/RegexInterpreter.h:
+ * yarr/RegexJIT.h:
+ * yarr/RegexParser.h:
+ * yarr/RegexPattern.h:
+
+2010-03-06 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Eric Seidel.
+
+ [BREWMP] Share OwnPtr.
+ https://bugs.webkit.org/show_bug.cgi?id=35776
+
+ Share OwnPtr implementation with BREW MP and remove OwnPtrBrew.
+
+ * wtf/OwnPtrBrew.cpp: Added.
+ (WTF::deleteOwnedPtr):
+ * wtf/OwnPtrCommon.h:
+ * wtf/brew/OwnPtrBrew.cpp: Removed.
+ * wtf/brew/OwnPtrBrew.h: Removed.
+
+2010-03-06 Patrick Gansterer <paroga@paroga.com>
+
+ Reviewed by Eric Seidel.
+
+ Implemented JIT_OPTIMIZE_NATIVE_CALL for WinCE
+ https://bugs.webkit.org/show_bug.cgi?id=33426
+
+ * jit/JITOpcodes.cpp:
+ (JSC::JIT::privateCompileCTIMachineTrampolines):
+
+2010-03-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (build fix).
+
+ Add enw exports to windows
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-05 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ JSC should cache int to Identifier conversion as it does for ordinary strings
+ https://bugs.webkit.org/show_bug.cgi?id=35814
+
+ Make the NumericStrings cache cache unsigned ints in addition to signed.
+ We keep them separate from the int cache as it both simplifies code, and
+ also because the unsigned path is exclusive to property access and therefore
+ seems to have different usage patterns.
+
+ The primary trigger for the unsigned to Identifier propertyName conversion
+ is the construction of array-like objects out of normal objects. Given these
+ tend to be relative small numbers, and the array-like behaviour lends itself
+ to sequential values this patch also adds a non-colliding cache for all small
+ numbers.
+
+ * JavaScriptCore.exp:
+ * runtime/Identifier.cpp:
+ (JSC::Identifier::from):
+ * runtime/Identifier.h:
+ * runtime/NumericStrings.h:
+ (JSC::NumericStrings::add):
+ (JSC::NumericStrings::lookup):
+ (JSC::NumericStrings::lookupSmallString):
+
+2010-03-03 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Allow static property getters to interact with JSCs caching
+ https://bugs.webkit.org/show_bug.cgi?id=35716
+
+ Add new opcodes for handling cached lookup of static value getters.
+ More or less the same as with JS getters, all that changes is that
+ instead of calling through a JSFunction we always know that we have
+ a C function to call.
+
+ For the patching routines in the JIT we now need to pass a few
+ new parameters to allow us to pass enough information to the stub
+ function to allow us to call the C function correctly. Logically
+ this shouldn't actually be necessary as all of these functions ignore
+ the identifier, but removing the ident parameter would require
+ somewhat involved changes to the way we implement getOwnPropertySlot,
+ etc.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::dump):
+ (JSC::CodeBlock::derefStructures):
+ (JSC::CodeBlock::refStructures):
+ * bytecode/Instruction.h:
+ (JSC::Instruction::Instruction):
+ (JSC::Instruction::):
+ * bytecode/Opcode.h:
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::tryCacheGetByID):
+ (JSC::Interpreter::privateExecute):
+ * jit/JIT.cpp:
+ (JSC::JIT::privateCompileMainPass):
+ * jit/JIT.h:
+ (JSC::JIT::compileGetByIdProto):
+ (JSC::JIT::compileGetByIdSelfList):
+ (JSC::JIT::compileGetByIdProtoList):
+ (JSC::JIT::compileGetByIdChainList):
+ (JSC::JIT::compileGetByIdChain):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCacheGetByID):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ (JSC::):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::getOwnPropertySlot):
+ * runtime/Lookup.h:
+ (JSC::getStaticPropertySlot):
+ (JSC::getStaticValueSlot):
+ * runtime/PropertySlot.h:
+ (JSC::PropertySlot::):
+ (JSC::PropertySlot::PropertySlot):
+ (JSC::PropertySlot::cachedPropertyType):
+ (JSC::PropertySlot::isCacheable):
+ (JSC::PropertySlot::isCacheableValue):
+ (JSC::PropertySlot::setValueSlot):
+ (JSC::PropertySlot::setCacheableCustom):
+ (JSC::PropertySlot::setGetterSlot):
+ (JSC::PropertySlot::setCacheableGetterSlot):
+ (JSC::PropertySlot::clearOffset):
+ (JSC::PropertySlot::customGetter):
+
+2010-03-04 Shinichiro Hamaji <hamaji@chromium.org>
+
+ Unreviewed. Remove a non-ASCII character introduced in the following bug.
+
+ put_by_id does will incorrectly cache writes where a specific value exists, where at the point of caching the same value is being written.
+ https://bugs.webkit.org/show_bug.cgi?id=35537
+
+ * runtime/JSObject.h:
+ (JSC::JSObject::putDirectInternal):
+
+2010-03-04 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ [Qt] Make the OUTPUT_DIR variable in qmake projects independent of build-webkit's logic.
+
+ This also allows shadow builds relying only on qmake to work properly.
+ * jsc.pro:
+ * qt/api/QtScript.pro:
+ * qt/tests/qscriptengine/qscriptengine.pro:
+ * qt/tests/qscriptvalue/qscriptvalue.pro:
+ * qt/tests/tests.pri:
+
+2010-03-03 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ QScriptValue::isObject fix.
+
+ Fix broken internal state evaluation from JSValue to JSNative / JSObject.
+ New function was introduced which should take care about promoting
+ JSValue state inside QScriptValuePrivate. It should be used instead of a
+ direct JSC C API call.
+
+ The bug exposed a weakness in autotest suite, as the QScriptValuePrivate
+ is based on state machine with lazy state evaluation, there is a possibility
+ that serial sequencial calls to the same public const function could return
+ different results. The patch fix the issue.
+
+ [Qt] Sometimes QScriptValue::isObject returns an incorrect value
+ https://bugs.webkit.org/show_bug.cgi?id=35387
+
+ * qt/api/qscriptvalue_p.h:
+ (QScriptValuePrivate::isBool):
+ (QScriptValuePrivate::isNumber):
+ (QScriptValuePrivate::isNull):
+ (QScriptValuePrivate::isString):
+ (QScriptValuePrivate::isUndefined):
+ (QScriptValuePrivate::isError):
+ (QScriptValuePrivate::isObject):
+ (QScriptValuePrivate::isFunction):
+ (QScriptValuePrivate::call):
+ (QScriptValuePrivate::refineJSValue):
+ * qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp:
+ (tst_QScriptValue::initScriptValues):
+ (tst_QScriptValue::isValid_makeData):
+ (tst_QScriptValue::isValid_test):
+ (tst_QScriptValue::isBool_makeData):
+ (tst_QScriptValue::isBool_test):
+ (tst_QScriptValue::isBoolean_makeData):
+ (tst_QScriptValue::isBoolean_test):
+ (tst_QScriptValue::isNumber_makeData):
+ (tst_QScriptValue::isNumber_test):
+ (tst_QScriptValue::isFunction_test):
+ (tst_QScriptValue::isNull_makeData):
+ (tst_QScriptValue::isNull_test):
+ (tst_QScriptValue::isString_makeData):
+ (tst_QScriptValue::isString_test):
+ (tst_QScriptValue::isUndefined_makeData):
+ (tst_QScriptValue::isUndefined_test):
+ (tst_QScriptValue::isObject_makeData):
+ (tst_QScriptValue::isObject_test):
+ (tst_QScriptValue::toString_makeData):
+ (tst_QScriptValue::toString_test):
+ (tst_QScriptValue::toNumber_makeData):
+ (tst_QScriptValue::toNumber_test):
+ (tst_QScriptValue::toBool_makeData):
+ (tst_QScriptValue::toBool_test):
+ (tst_QScriptValue::toBoolean_makeData):
+ (tst_QScriptValue::toBoolean_test):
+ (tst_QScriptValue::toInteger_makeData):
+ (tst_QScriptValue::toInteger_test):
+ (tst_QScriptValue::toInt32_makeData):
+ (tst_QScriptValue::toInt32_test):
+ (tst_QScriptValue::toUInt32_makeData):
+ (tst_QScriptValue::toUInt32_test):
+ (tst_QScriptValue::toUInt16_makeData):
+ (tst_QScriptValue::toUInt16_test):
+
+2010-03-03 Chao-ying Fu <fu@mips.com>
+
+ Reviewed by Gavin Barraclough.
+
+ MIPS JIT Supports
+ https://bugs.webkit.org/show_bug.cgi?id=30144
+
+ The following changes enable MIPS YARR and YARR_JIT.
+
+ * assembler/AbstractMacroAssembler.h:
+ (JSC::AbstractMacroAssembler::Imm32::Imm32):
+ * assembler/MIPSAssembler.h: Added.
+ (JSC::MIPSRegisters::):
+ (JSC::MIPSAssembler::MIPSAssembler):
+ (JSC::MIPSAssembler::):
+ (JSC::MIPSAssembler::JmpSrc::JmpSrc):
+ (JSC::MIPSAssembler::JmpDst::JmpDst):
+ (JSC::MIPSAssembler::JmpDst::isUsed):
+ (JSC::MIPSAssembler::JmpDst::used):
+ (JSC::MIPSAssembler::emitInst):
+ (JSC::MIPSAssembler::nop):
+ (JSC::MIPSAssembler::loadDelayNop):
+ (JSC::MIPSAssembler::copDelayNop):
+ (JSC::MIPSAssembler::move):
+ (JSC::MIPSAssembler::li):
+ (JSC::MIPSAssembler::lui):
+ (JSC::MIPSAssembler::addiu):
+ (JSC::MIPSAssembler::addu):
+ (JSC::MIPSAssembler::subu):
+ (JSC::MIPSAssembler::mult):
+ (JSC::MIPSAssembler::mfhi):
+ (JSC::MIPSAssembler::mflo):
+ (JSC::MIPSAssembler::mul):
+ (JSC::MIPSAssembler::andInsn):
+ (JSC::MIPSAssembler::andi):
+ (JSC::MIPSAssembler::nor):
+ (JSC::MIPSAssembler::orInsn):
+ (JSC::MIPSAssembler::ori):
+ (JSC::MIPSAssembler::xorInsn):
+ (JSC::MIPSAssembler::xori):
+ (JSC::MIPSAssembler::slt):
+ (JSC::MIPSAssembler::sltu):
+ (JSC::MIPSAssembler::sltiu):
+ (JSC::MIPSAssembler::sll):
+ (JSC::MIPSAssembler::sllv):
+ (JSC::MIPSAssembler::sra):
+ (JSC::MIPSAssembler::srav):
+ (JSC::MIPSAssembler::lw):
+ (JSC::MIPSAssembler::lwl):
+ (JSC::MIPSAssembler::lwr):
+ (JSC::MIPSAssembler::lhu):
+ (JSC::MIPSAssembler::sw):
+ (JSC::MIPSAssembler::jr):
+ (JSC::MIPSAssembler::jalr):
+ (JSC::MIPSAssembler::jal):
+ (JSC::MIPSAssembler::bkpt):
+ (JSC::MIPSAssembler::bgez):
+ (JSC::MIPSAssembler::bltz):
+ (JSC::MIPSAssembler::beq):
+ (JSC::MIPSAssembler::bne):
+ (JSC::MIPSAssembler::bc1t):
+ (JSC::MIPSAssembler::bc1f):
+ (JSC::MIPSAssembler::newJmpSrc):
+ (JSC::MIPSAssembler::appendJump):
+ (JSC::MIPSAssembler::addd):
+ (JSC::MIPSAssembler::subd):
+ (JSC::MIPSAssembler::muld):
+ (JSC::MIPSAssembler::lwc1):
+ (JSC::MIPSAssembler::ldc1):
+ (JSC::MIPSAssembler::swc1):
+ (JSC::MIPSAssembler::sdc1):
+ (JSC::MIPSAssembler::mtc1):
+ (JSC::MIPSAssembler::mfc1):
+ (JSC::MIPSAssembler::truncwd):
+ (JSC::MIPSAssembler::cvtdw):
+ (JSC::MIPSAssembler::ceqd):
+ (JSC::MIPSAssembler::cngtd):
+ (JSC::MIPSAssembler::cnged):
+ (JSC::MIPSAssembler::cltd):
+ (JSC::MIPSAssembler::cled):
+ (JSC::MIPSAssembler::cueqd):
+ (JSC::MIPSAssembler::coled):
+ (JSC::MIPSAssembler::coltd):
+ (JSC::MIPSAssembler::culed):
+ (JSC::MIPSAssembler::cultd):
+ (JSC::MIPSAssembler::label):
+ (JSC::MIPSAssembler::align):
+ (JSC::MIPSAssembler::getRelocatedAddress):
+ (JSC::MIPSAssembler::getDifferenceBetweenLabels):
+ (JSC::MIPSAssembler::size):
+ (JSC::MIPSAssembler::executableCopy):
+ (JSC::MIPSAssembler::getCallReturnOffset):
+ (JSC::MIPSAssembler::linkJump):
+ (JSC::MIPSAssembler::linkCall):
+ (JSC::MIPSAssembler::linkPointer):
+ (JSC::MIPSAssembler::relinkJump):
+ (JSC::MIPSAssembler::relinkCall):
+ (JSC::MIPSAssembler::repatchInt32):
+ (JSC::MIPSAssembler::repatchPointer):
+ (JSC::MIPSAssembler::repatchLoadPtrToLEA):
+ (JSC::MIPSAssembler::relocateJumps):
+ (JSC::MIPSAssembler::linkWithOffset):
+ (JSC::MIPSAssembler::linkCallInternal):
+ * assembler/MacroAssembler.h:
+ * assembler/MacroAssemblerMIPS.h: Added.
+ (JSC::MacroAssemblerMIPS::MacroAssemblerMIPS):
+ (JSC::MacroAssemblerMIPS::):
+ (JSC::MacroAssemblerMIPS::add32):
+ (JSC::MacroAssemblerMIPS::and32):
+ (JSC::MacroAssemblerMIPS::lshift32):
+ (JSC::MacroAssemblerMIPS::mul32):
+ (JSC::MacroAssemblerMIPS::not32):
+ (JSC::MacroAssemblerMIPS::or32):
+ (JSC::MacroAssemblerMIPS::rshift32):
+ (JSC::MacroAssemblerMIPS::sub32):
+ (JSC::MacroAssemblerMIPS::xor32):
+ (JSC::MacroAssemblerMIPS::load32):
+ (JSC::MacroAssemblerMIPS::load32WithUnalignedHalfWords):
+ (JSC::MacroAssemblerMIPS::load32WithAddressOffsetPatch):
+ (JSC::MacroAssemblerMIPS::loadPtrWithPatchToLEA):
+ (JSC::MacroAssemblerMIPS::loadPtrWithAddressOffsetPatch):
+ (JSC::MacroAssemblerMIPS::load16):
+ (JSC::MacroAssemblerMIPS::store32WithAddressOffsetPatch):
+ (JSC::MacroAssemblerMIPS::store32):
+ (JSC::MacroAssemblerMIPS::supportsFloatingPoint):
+ (JSC::MacroAssemblerMIPS::supportsFloatingPointTruncate):
+ (JSC::MacroAssemblerMIPS::pop):
+ (JSC::MacroAssemblerMIPS::push):
+ (JSC::MacroAssemblerMIPS::move):
+ (JSC::MacroAssemblerMIPS::swap):
+ (JSC::MacroAssemblerMIPS::signExtend32ToPtr):
+ (JSC::MacroAssemblerMIPS::zeroExtend32ToPtr):
+ (JSC::MacroAssemblerMIPS::branch32):
+ (JSC::MacroAssemblerMIPS::branch32WithUnalignedHalfWords):
+ (JSC::MacroAssemblerMIPS::branch16):
+ (JSC::MacroAssemblerMIPS::branchTest32):
+ (JSC::MacroAssemblerMIPS::jump):
+ (JSC::MacroAssemblerMIPS::branchAdd32):
+ (JSC::MacroAssemblerMIPS::branchMul32):
+ (JSC::MacroAssemblerMIPS::branchSub32):
+ (JSC::MacroAssemblerMIPS::breakpoint):
+ (JSC::MacroAssemblerMIPS::nearCall):
+ (JSC::MacroAssemblerMIPS::call):
+ (JSC::MacroAssemblerMIPS::ret):
+ (JSC::MacroAssemblerMIPS::set32):
+ (JSC::MacroAssemblerMIPS::setTest32):
+ (JSC::MacroAssemblerMIPS::moveWithPatch):
+ (JSC::MacroAssemblerMIPS::branchPtrWithPatch):
+ (JSC::MacroAssemblerMIPS::storePtrWithPatch):
+ (JSC::MacroAssemblerMIPS::tailRecursiveCall):
+ (JSC::MacroAssemblerMIPS::makeTailRecursiveCall):
+ (JSC::MacroAssemblerMIPS::loadDouble):
+ (JSC::MacroAssemblerMIPS::storeDouble):
+ (JSC::MacroAssemblerMIPS::addDouble):
+ (JSC::MacroAssemblerMIPS::subDouble):
+ (JSC::MacroAssemblerMIPS::mulDouble):
+ (JSC::MacroAssemblerMIPS::convertInt32ToDouble):
+ (JSC::MacroAssemblerMIPS::insertRelaxationWords):
+ (JSC::MacroAssemblerMIPS::branchTrue):
+ (JSC::MacroAssemblerMIPS::branchFalse):
+ (JSC::MacroAssemblerMIPS::branchEqual):
+ (JSC::MacroAssemblerMIPS::branchNotEqual):
+ (JSC::MacroAssemblerMIPS::branchDouble):
+ (JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
+ (JSC::MacroAssemblerMIPS::linkCall):
+ (JSC::MacroAssemblerMIPS::repatchCall):
+ * jit/ExecutableAllocator.h:
+ (JSC::ExecutableAllocator::cacheFlush):
+ * wtf/Platform.h:
+ * yarr/RegexJIT.cpp:
+ (JSC::Yarr::RegexGenerator::generateEnter):
+ (JSC::Yarr::RegexGenerator::generateReturn):
+
+2010-03-03 Steve Falkenburg <sfalken@apple.com>
+
+ Windows build fix.
+
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+ * JavaScriptCore.vcproj/jsc/jscCommon.vsprops:
+
+2010-03-03 Steve Falkenburg <sfalken@apple.com>
+
+ Windows build fix.
+
+ * JavaScriptCore.vcproj/jsc/jsc.vcproj:
+
+2010-03-03 Mark Rowe <mrowe@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Add virtual memory tags for TCMalloc and WebCore's purgeable buffers.
+
+ * wtf/TCSystemAlloc.cpp:
+ (TryMmap): Use the VM tag.
+ * wtf/VMTags.h: Make use of VM_MEMORY_TCMALLOC and VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS.
+
+2010-03-03 Steve Falkenburg <sfalken@apple.com>
+
+ Rubber stamped by Adam Roben.
+
+ Fix bogus xcopy that was polluting source tree at build time.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+
+2010-03-02 Fridrich Strba <fridrich.strba@bluewin.ch>
+
+ Reviewed by Oliver Hunt.
+
+ Allow building smoothly on win32 and win64 using GCC
+ https://bugs.webkit.org/show_bug.cgi?id=35607
+
+ * jit/JITStubs.h:
+ * runtime/Collector.cpp:
+ (JSC::Heap::allocateBlock):
+ (JSC::Heap::freeBlockPtr):
+ (JSC::currentThreadStackBase):
+
+2010-03-02 Jeremy Orlow <jorlow@chromium.org>
+
+ Reviewed by David Levin.
+
+ Revert database thread changes that are no longer required
+ https://bugs.webkit.org/show_bug.cgi?id=35519
+
+ Jochen Eisinger created 55214 and 55247 to track which database
+ owns which thread. Dmitry suggested that this could also
+ be done via TLS, though. After exploring the options, Jochen
+ chose to go the TLS route, so these patches are no longer needed.
+
+ * wtf/Threading.h:
+ * wtf/ThreadingNone.cpp:
+ (WTF::isMainThread):
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::identifierByPthreadHandle):
+ (WTF::establishIdentifierForPthreadHandle):
+ (WTF::pthreadHandleForIdentifier):
+ (WTF::createThreadInternal):
+ (WTF::currentThread):
+ * wtf/ThreadingWin.cpp:
+ (WTF::threadMap):
+ (WTF::storeThreadHandleByIdentifier):
+ (WTF::threadHandleForIdentifier):
+ (WTF::createThreadInternal):
+
+2010-03-02 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix QScriptValue::toString().
+
+ More ECMA Script compliance, especially for values as NaN, Inifinite
+ and really big/small numbers.
+
+ [Qt] QScriptValue::toString() returns incorrect values
+ https://bugs.webkit.org/show_bug.cgi?id=34850
+
+ * qt/api/qscriptconverter_p.h:
+ (QScriptConverter::toString):
+ * qt/api/qscriptvalue_p.h:
+ (QScriptValuePrivate::toString):
+ * qt/tests/qscriptvalue/tst_qscriptvalue.cpp:
+ * qt/tests/qscriptvalue/tst_qscriptvalue.h:
+ * qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp:
+ (tst_QScriptValue::toString_initData):
+ (tst_QScriptValue::toString_makeData):
+ (tst_QScriptValue::toString_test):
+
+2010-03-02 Jedrzej Nowacki <jedrzej.nowacki@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Introduce a new class; QScriptString.
+
+ The QScriptString class should act as a handle to "interned"
+ strings in a QScriptEngine.
+
+ [Qt] QtScript should provide QScriptString
+ https://bugs.webkit.org/show_bug.cgi?id=34843
+
+ * qt/api/QtScript.pro:
+ * qt/api/qscriptengine.cpp:
+ (QScriptEngine::toStringHandle):
+ * qt/api/qscriptengine.h:
+ * qt/api/qscriptengine_p.h:
+ (QScriptEnginePrivate::toStringHandle):
+ * qt/api/qscriptstring.cpp: Added.
+ (QScriptString::QScriptString):
+ (QScriptString::~QScriptString):
+ (QScriptString::operator=):
+ (QScriptString::isValid):
+ (QScriptString::operator==):
+ (QScriptString::operator!=):
+ (QScriptString::toArrayIndex):
+ (QScriptString::toString):
+ (QScriptString::operator QString):
+ (qHash):
+ * qt/api/qscriptstring.h: Added.
+ * qt/api/qscriptstring_p.h: Added.
+ (QScriptStringPrivate::QScriptStringPrivate):
+ (QScriptStringPrivate::~QScriptStringPrivate):
+ (QScriptStringPrivate::get):
+ (QScriptStringPrivate::isValid):
+ (QScriptStringPrivate::operator==):
+ (QScriptStringPrivate::operator!=):
+ (QScriptStringPrivate::toArrayIndex):
+ (QScriptStringPrivate::toString):
+ (QScriptStringPrivate::id):
+ * qt/tests/qscriptstring/qscriptstring.pro: Added.
+ * qt/tests/qscriptstring/tst_qscriptstring.cpp: Added.
+ (tst_QScriptString::tst_QScriptString):
+ (tst_QScriptString::~tst_QScriptString):
+ (tst_QScriptString::test):
+ (tst_QScriptString::hash):
+ (tst_QScriptString::toArrayIndex_data):
+ (tst_QScriptString::toArrayIndex):
+ * qt/tests/tests.pro:
+
+2010-03-02 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by NOBODY (Build fix).
+
+ Export function on windows.
+
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
+
+2010-03-01 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Refactor named getter function signature to be in line with indexing getter signature
+ https://bugs.webkit.org/show_bug.cgi?id=35563
+
+ This removes the PropertySlot argument from getter functions, and makes them directly
+ pass the slot base. This makes the semantics for the functions match that of the
+ indexing getters.
+
+ On the down side, this means that we can no longer simply use a proxy function for
+ JS getters, so we now add another marker value to indicate that a getter is present
+ and branch accordingly.
+
+ Against all rationality sunspider reports this as a perf win, but i suspect it's just noise.
+
+ * API/JSCallbackObject.h:
+ * API/JSCallbackObjectFunctions.h:
+ (JSC::::staticValueGetter):
+ (JSC::::staticFunctionGetter):
+ (JSC::::callbackGetter):
+ * JavaScriptCore.exp:
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::argumentsGetter):
+ * runtime/JSActivation.h:
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::argumentsGetter):
+ (JSC::JSFunction::callerGetter):
+ (JSC::JSFunction::lengthGetter):
+ * runtime/JSFunction.h:
+ * runtime/NumberConstructor.cpp:
+ (JSC::numberConstructorNaNValue):
+ (JSC::numberConstructorNegInfinity):
+ (JSC::numberConstructorPosInfinity):
+ (JSC::numberConstructorMaxValue):
+ (JSC::numberConstructorMinValue):
+ * runtime/PropertySlot.cpp:
+ (JSC::PropertySlot::functionGetter):
+ * runtime/PropertySlot.h:
+ (JSC::PropertySlot::getValue):
+ (JSC::PropertySlot::setGetterSlot):
+ (JSC::PropertySlot::setCacheableGetterSlot):
+ * runtime/RegExpConstructor.cpp:
+ (JSC::regExpConstructorDollar1):
+ (JSC::regExpConstructorDollar2):
+ (JSC::regExpConstructorDollar3):
+ (JSC::regExpConstructorDollar4):
+ (JSC::regExpConstructorDollar5):
+ (JSC::regExpConstructorDollar6):
+ (JSC::regExpConstructorDollar7):
+ (JSC::regExpConstructorDollar8):
+ (JSC::regExpConstructorDollar9):
+ (JSC::regExpConstructorInput):
+ (JSC::regExpConstructorMultiline):
+ (JSC::regExpConstructorLastMatch):
+ (JSC::regExpConstructorLastParen):
+ (JSC::regExpConstructorLeftContext):
+ (JSC::regExpConstructorRightContext):
+ * runtime/RegExpObject.cpp:
+ (JSC::regExpObjectGlobal):
+ (JSC::regExpObjectIgnoreCase):
+ (JSC::regExpObjectMultiline):
+ (JSC::regExpObjectSource):
+ (JSC::regExpObjectLastIndex):
+
+2010-03-01 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ PropertySlot::getValue(ExecState, unsigned) unnecessarily converts index to an Identifier
+ https://bugs.webkit.org/show_bug.cgi?id=35561
+
+ Fix this by defining a separate property getter function for index getters. This allows
+ us to pass an unsigned number without the conversion to an Identifier. We then update
+ setCustomIndex to take this new getter type.
+
+ * runtime/PropertySlot.h:
+ (JSC::PropertySlot::getValue):
+ (JSC::PropertySlot::setCustom):
+ (JSC::PropertySlot::setCustomIndex):
+
+2010-03-01 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Bug 35537 - put_by_id does will incorrectly cache writes where a specific value exists,
+ where at the point of caching the same value is being written.
+
+ When performing a put_by_id that is replacing a property already present on the object,
+ there are three interesting cases regarding the state of the specific value:
+
+ (1) No specific value set - nothing to do, leave the structure in it's current state,
+ can cache.
+ (2) A specific value was set, the new put is not of a specified value (i.e. function),
+ or is of a different specific value - in these cases we need to perform a despecifying
+ transition to clear the specific value in the structure, but having done so this is a
+ normal property so as such we can again cache normally.
+ (3) A specific value was set, and we are overwriting with the same value - in these cases
+ leave the structure unchanged, but since a specific value is set we cannot cache this
+ put (we would need the JIT to dynamically check the value being written matched).
+
+ Unfortunately, the current behaviour does not match this. the checks for a specific value
+ being present & the value matching are combined in such a way that in case (2), above we
+ will unnecessarily prevent the transition being cached, but in case (3) we will incorrectly
+ fail to prevent caching.
+
+ The bug exposes itself if multiple puts of the same specific value are performed to a
+ property, and erroneously the put is allowed to be cached by the JIT. Method checks may be
+ generated caching calls of this structure. Subsequent puts performed from JIT code may
+ write different values without triggering a despecify transition, and as such cached method
+ checks will continue to pass, despite the value having changed.
+
+ * runtime/JSObject.h:
+ (JSC::JSObject::putDirectInternal):
+
+2010-03-01 Tor Arne Vestbø <tor.arne.vestbo@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ Fix the Qt build on Mac OS X/Cocoa 64-bit
+
+ * JavaScriptCore.pri: Add missing implementation file to resolve JSC symbols
+
+2010-02-26 Gavin Barraclough <barraclough@apple.com>
+
+ Rubber Stamped by Geoff Garen.
+
+ Remove wrec. All builds should have switched to yarr by now.
+
+ * Android.mk:
+ * GNUmakefile.am:
+ * JavaScriptCore.gypi:
+ * JavaScriptCore.pri:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj:
+ * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops:
+ * JavaScriptCore.vcproj/jsc/jscCommon.vsprops:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/RegExp.cpp:
+ (JSC::RegExp::match):
+ * runtime/RegExp.h:
+ * wrec: Removed.
+ * wrec/CharacterClass.cpp: Removed.
+ * wrec/CharacterClass.h: Removed.
+ * wrec/CharacterClassConstructor.cpp: Removed.
+ * wrec/CharacterClassConstructor.h: Removed.
+ * wrec/Escapes.h: Removed.
+ * wrec/Quantifier.h: Removed.
+ * wrec/WREC.cpp: Removed.
+ * wrec/WREC.h: Removed.
+ * wrec/WRECFunctors.cpp: Removed.
+ * wrec/WRECFunctors.h: Removed.
+ * wrec/WRECGenerator.cpp: Removed.
+ * wrec/WRECGenerator.h: Removed.
+ * wrec/WRECParser.cpp: Removed.
+ * wrec/WRECParser.h: Removed.
+ * wscript:
+
+2010-02-26 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ Make the lookup table generator include an explicit cast to expected
+ type of the function. We do this because otherwise the blind intptr_t
+ cast that is subsequently applied allows incorrectly typed functions
+ to be inserted into the table, where they will only fail at runtime.
+ This change makes such errors produce a compile time failure.
+
+ * create_hash_table:
+
+2010-02-26 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Symbian specific getCPUTime implemetation
+ https://bugs.webkit.org/show_bug.cgi?id=34742
+
+ Default implementation doesn't work on Symbian devices.
+ This change adds a proper implementation by
+ asking thread execution time from the current thread.
+
+ * runtime/TimeoutChecker.cpp:
+ (JSC::getCPUTime):
+
+2010-02-25 Alexey Proskuryakov <ap@apple.com>
+
+ Reviewed by Anders Carlsson.
+
+ https://bugs.webkit.org/show_bug.cgi?id=35406
+ <rdar://problem/6945502> Make generic array methods work with JavaArray
+
+ Renamed lazyCreationData to subclassData. This is extra data that can be used by JSArray
+ subclasses (you can't add new data members, because it wouldn't fit in JSCell otherwise).
+
+ * JavaScriptCore.exp:
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::JSArray):
+ (JSC::JSArray::subclassData):
+ (JSC::JSArray::setSubclassData):
+ * runtime/JSArray.h:
+ * runtime/RegExpConstructor.cpp:
+ (JSC::RegExpMatchesArray::RegExpMatchesArray):
+ (JSC::RegExpMatchesArray::~RegExpMatchesArray):
+ (JSC::RegExpMatchesArray::fillArrayInstance):
+ * runtime/RegExpMatchesArray.h:
+ (JSC::RegExpMatchesArray::getOwnPropertySlot):
+ (JSC::RegExpMatchesArray::getOwnPropertyDescriptor):
+ (JSC::RegExpMatchesArray::put):
+ (JSC::RegExpMatchesArray::deleteProperty):
+ (JSC::RegExpMatchesArray::getOwnPropertyNames):
+
+2010-02-25 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoff Garen.
+
+ JSC crashes like crazy in the JSPropertyNameIterator destructor
+
+ Add back null check of m_cachedStructure. Curse last minute changes.
+
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::~JSPropertyNameIterator):
+
+2010-02-25 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Race condition in JSPropertyNameIterator and Structure destruction
+ https://bugs.webkit.org/show_bug.cgi?id=35398
+
+ JSPropertyNameIterator and Structure have a cyclic dependency that they
+ manage by clearing the appropriate reference in each other during their
+ destruction. However if the Structure is destroyed while the
+ JSPropertyNameIterator is dead but not yet finalized the Structures
+ WeakGCPtr will return null, and so prevent Structure from clearing
+ the m_cachedStructure pointer of the iterator. When the iterator is
+ then finalised the m_cachedStructure is invalid, and the attempt to
+ clear the structures back reference fails.
+
+ To fix this we simply make JSPropertyNameIterator keep the Structure
+ alive, using the weak pointer to break the ref cycle.
+
+ * runtime/JSPropertyNameIterator.cpp:
+ (JSC::JSPropertyNameIterator::~JSPropertyNameIterator):
+ The iterator now keeps m_cachedStructure alive itself, so no longer needs
+ to check for it being cleared
+ * runtime/JSPropertyNameIterator.h:
+ (JSC::JSPropertyNameIterator::setCachedStructure):
+ Add an assertion to ensure correct usage
+ (JSC::JSPropertyNameIterator::cachedStructure):
+ Add .get()
+ * runtime/Structure.cpp:
+ (JSC::Structure::~Structure):
+ Add an assertion that our iterator isn't already dead, and remove
+ the now unnecessary attempt to clear the ref in the iterator
+ * runtime/WeakGCPtr.h:
+ (JSC::WeakGCPtr::hasDeadObject):
+ An assert-only function to allow us to assert correct behaviour
+ in the Structure destructor
+
+2010-02-25 Jochen Eisinger <jochen@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Make the context that was passed to the ThreadFunction accessible.
+ https://bugs.webkit.org/show_bug.cgi?id=35379
+
+ When a database is opened, right now you
+ don't have any context from where it is opened. The problem is that
+ the actual calls that open a database go through the sqlite3 vfs
+ layer, so there's no easy way to pass this function down to to
+ platform/sql/chromium/SQLFileSystemChromium*.cpp
+
+ This patch will allow you to get from anywhere within webkit a pointer
+ to the Thread object that actually created the thread you're currently
+ on (in case of the database, this can be either a thread forked of
+ from the main thread or from a worker thread), and query the object
+ for context information.
+
+ * wtf/Threading.h:
+ * wtf/ThreadingNone.cpp:
+ (WTF::threadContext):
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::):
+ (WTF::identifierByPthreadHandle):
+ (WTF::establishIdentifierForPthreadHandle):
+ (WTF::pthreadHandleForIdentifier):
+ (WTF::contextForIdentifier):
+ (WTF::createThreadInternal):
+ (WTF::currentThread):
+ (WTF::threadContext):
+ * wtf/ThreadingWin.cpp:
+ (WTF::):
+ (WTF::threadMap):
+ (WTF::storeThreadHandleByIdentifier):
+ (WTF::threadHandleForIdentifier):
+ (WTF::contextForIdentifier):
+ (WTF::createThreadInternal):
+ (WTF::threadContext):
+
+2010-02-25 Jeremy Orlow <jorlow@chromium.org>
+
+ Reverting to re-submit with better change log.
+
+ * wtf/Threading.h:
+ * wtf/ThreadingNone.cpp:
+ (WTF::isMainThread):
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::identifierByPthreadHandle):
+ (WTF::establishIdentifierForPthreadHandle):
+ (WTF::pthreadHandleForIdentifier):
+ (WTF::createThreadInternal):
+ (WTF::currentThread):
+ * wtf/ThreadingWin.cpp:
+ (WTF::threadMap):
+ (WTF::storeThreadHandleByIdentifier):
+ (WTF::threadHandleForIdentifier):
+ (WTF::createThreadInternal):
+
+2010-02-25 Jochen Eisinger <jochen@chromium.org>
+
+ Reviewed by Jeremy Orlow.
+
+ Make the context that was passed to the ThreadFunction accessible.
+ https://bugs.webkit.org/show_bug.cgi?id=35379
+
+ * wtf/Threading.h:
+ * wtf/ThreadingNone.cpp:
+ (WTF::threadContext):
+ * wtf/ThreadingPthreads.cpp:
+ (WTF::):
+ (WTF::identifierByPthreadHandle):
+ (WTF::establishIdentifierForPthreadHandle):
+ (WTF::pthreadHandleForIdentifier):
+ (WTF::contextForIdentifier):
+ (WTF::createThreadInternal):
+ (WTF::currentThread):
+ (WTF::threadContext):
+ * wtf/ThreadingWin.cpp:
+ (WTF::):
+ (WTF::threadMap):
+ (WTF::storeThreadHandleByIdentifier):
+ (WTF::threadHandleForIdentifier):
+ (WTF::contextForIdentifier):
+ (WTF::createThreadInternal):
+ (WTF::threadContext):
+
+2010-02-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Geoffrey Garen.
+
+ [REGRESSION in r55185] EXC_BAD_ACCESS on opening inspector.
+ https://bugs.webkit.org/show_bug.cgi?id=35335
+
+ compileGetDirectOffset modifies the contents of the object register
+ when the object is not using the inline storage array. As the object
+ register contains our 'this' pointer we can't allow it to be clobbered.
+ The fix is simply to copy the register into a separate scratch register
+ when we're loading off an object that doesn't use inline storage.
+
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::privateCompileGetByIdSelfList):
+
+2010-02-24 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Gavin Barraclough.
+
+ Speed up getter performance in the jit
+ https://bugs.webkit.org/show_bug.cgi?id=35332
+
+ Implement getter lookup caching in the interpreter.
+ The getter stubs are generated through basically the
+ same code paths as the normal get_by_id caching.
+ Instead of simply loading a property and returning,
+ we load the getter slot, and pass the getter, base value
+ and return address to a shared stub used for getter
+ dispatch.
+
+ * jit/JIT.h:
+ (JSC::JIT::compileGetByIdProto):
+ (JSC::JIT::compileGetByIdSelfList):
+ (JSC::JIT::compileGetByIdProtoList):
+ (JSC::JIT::compileGetByIdChainList):
+ (JSC::JIT::compileGetByIdChain):
+ * jit/JITPropertyAccess.cpp:
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITPropertyAccess32_64.cpp:
+ (JSC::JIT::privateCompileGetByIdProto):
+ (JSC::JIT::privateCompileGetByIdSelfList):
+ (JSC::JIT::privateCompileGetByIdProtoList):
+ (JSC::JIT::privateCompileGetByIdChainList):
+ (JSC::JIT::privateCompileGetByIdChain):
+ * jit/JITStubs.cpp:
+ (JSC::JITThunks::tryCacheGetByID):
+ (JSC::DEFINE_STUB_FUNCTION):
+ * jit/JITStubs.h:
+ (JSC::):
+ * runtime/GetterSetter.h:
+
+2010-02-23 Oliver Hunt <oliver@apple.com>
+
+ Reviewed by Maciej Stachowiak.
+
+ Web Inspector: Regression: r55027+: Inspector broken
+ https://bugs.webkit.org/show_bug.cgi?id=35253
+
+ op_get_by_id_getter_chain was not passing the correct this parameter.
+ The bug was caused by incorrect use of baseCell instead of baseValue,
+ baseValue contains the original object for the lookup (and hence the
+ correct this object), baseCell is clobbered as part of walking the
+ prototype chain.
+
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::privateExecute):
+
+2010-02-23 Gustavo Noronha Silva <gns@gnome.org>
+
+ Rubber-stamped by Dimitri Glazkov.
+
+ Chromium build fix.
+
+ * JavaScriptCore.gyp/JavaScriptCore.gyp:
+
+2010-02-23 Leandro Pereira <leandro@profusion.mobi>
+
+ Reviewed by Gustavo Noronha Silva.
+
+ Changes references of GOwnPtr to reflect their new place.
+ http://webkit.org/b/35084
+
+ * JavaScriptCore/JavaScriptCore.gypi:
+ * JavaScriptCore/wtf/Threading.h:
+ * JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h:
+
+2010-02-23 Leandro Pereira <leandro@profusion.mobi>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Adding the EFL implementation of JavaScriptCore.
+ See https://bugs.webkit.org/show_bug.cgi?id=35084 for details.
+
+ * GNUmakefile.am: Updated to reflect the new location of GOwnPtr and
+ GRefPtr.
+ * wtf/efl/MainThreadEfl.cpp: Added.
+ * wtf/gobject/GOwnPtr.cpp: Moved from wtf/gtk.
+ * wtf/gobject/GOwnPtr.h: Moved from wtf/gtk.
+ * wtf/gobject/GRefPtr.cpp: Moved from wtf/gtk.
+ * wtf/gobject/GRefPtr.h: Moved from wtf/gtk.
+
+2010-02-22 Julien Chaffraix <jchaffraix@webkit.org>
+
+ Reviewed by Darin Adler.
+
+ Remove auto_ptr usage in JavaScriptCore.
+ https://bugs.webkit.org/show_bug.cgi?id=35221
+
+ * parser/Nodes.h: Removed now unneeded adopt method.
+ * parser/Parser.cpp: Removed <memory> include as it is not required anymore.
+ * wtf/OwnPtr.h: Removed the constructor from auto_ptr.
+ * wtf/VectorTraits.h: Removed a template specialization for auto_ptr.
+ * wtf/unicode/Collator.h: Made userDefault return a PassOwnPtr.
+ * wtf/unicode/CollatorDefault.cpp:
+ (WTF::Collator::userDefault): Changed the method to match the next signature.
+ * wtf/unicode/icu/CollatorICU.cpp:
+ (WTF::Collator::userDefault): Ditto.
+
+2010-02-22 Huahui Wu <hwu@google.com>
+
+ Reviewed by Eric Seidel.
+
+ Add code that enables SquirrelFish Extreme (a.k.a JSCX, JSC JIT)
+ in Android. It's disabled by default, but is enabled when the
+ enveronment variable ENABLE_JSC_JIT is set to true.
+ https://bugs.webkit.org/show_bug.cgi?id=34855
+
+ * Android.mk:
+ * wtf/Platform.h:
+
+2010-02-22 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ JSStringBuilder should not CRASH if allocation fails, it should throw a JSException.
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+ * runtime/JSStringBuilder.h:
+ (JSC::JSStringBuilder::JSStringBuilder):
+ (JSC::JSStringBuilder::append):
+ (JSC::JSStringBuilder::build):
+ * runtime/StringBuilder.h:
+ (JSC::StringBuilder::build):
+ * wtf/Vector.h:
+ (WTF::VectorBufferBase::tryAllocateBuffer):
+ (WTF::):
+ (WTF::VectorBuffer::tryAllocateBuffer):
+ (WTF::::tryExpandCapacity):
+ (WTF::::tryReserveCapacity):
+ (WTF::::tryAppend):
+
+2010-02-22 Kwang Yul Seo <skyul@company100.net>
+
+ Reviewed by Eric Seidel.
+
+ [BREWMP] Map FastMalloc to BREW memory allocator
+ https://bugs.webkit.org/show_bug.cgi?id=33570
+
+ 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.
+
+ * wtf/FastMalloc.cpp:
+ * wtf/brew/SystemMallocBrew.h: Added.
+ (mallocBrew):
+ (callocBrew):
+ (freeBrew):
+ (reallocBrew):
+
+2010-02-22 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
+
+ Build fix for make distcheck.
+
+ * GNUmakefile.am:
+
+2010-02-22 Laszlo Gombos <laszlo.1.gombos@nokia.com>
+
+ Unreviewed build fix.
+
+ [Qt] Build fix for RVCT.
+
+ Fix after r55024. The "-i" option is for perl not for the
+ script.
+
+ * DerivedSources.pro:
+
+2010-02-21 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ Make UString::m_data be const, and make the UChar owned/ref-counted by CrossThreadRefCounted be const too.
+
+ * runtime/UStringImpl.cpp:
+ (JSC::UStringImpl::baseSharedBuffer):
+ (JSC::UStringImpl::~UStringImpl):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::create):
+ (JSC::UStringImpl::data):
+ (JSC::UStringImpl::UStringImpl):
+ * wtf/OwnFastMallocPtr.h:
+ (WTF::OwnFastMallocPtr::~OwnFastMallocPtr):
+
+2010-02-21 Yuta Kitamura <yutak@chromium.org>
+
+ Reviewed by Darin Adler.
+
+ HashMapTranslatorAdapter::translate() needs to set the mapped value.
+
+ HTTPHeaderMap::add(const char*, const String&) does not work
+ https://bugs.webkit.org/show_bug.cgi?id=35227
+
+ * wtf/HashMap.h:
+ (WTF::HashMapTranslatorAdapter::translate):
+
+2010-02-19 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by David Levin.
+
+ Add an ENABLE flag for sandboxed iframes to make it possible to disable it in releases
+ https://bugs.webkit.org/show_bug.cgi?id=35147
+
+ * Configurations/FeatureDefines.xcconfig:
+
+2010-02-19 Gavin Barraclough <barraclough@apple.com>
+
+ Reviewed by Oliver Hunt.
+
+ JSString::getIndex() calls value() to resolve the string value (is a rope)
+ to a UString, then passes the result to jsSingleCharacterSubstring without
+ checking for an exception. In case of out-of-memory the returned UString
+ is null(), which may result in an out-of-buounds substring being created.
+ This is bad.
+
+ Simple fix is to be able to get an index from a rope without resolving to
+ UString. This may be a useful optimization in some test cases.
+
+ The same bug exists in some other methods is JSString, these can be fixed
+ by changing them to call getIndex().
+
+ * runtime/JSString.cpp:
+ (JSC::JSString::resolveRope):
+ (JSC::JSString::getStringPropertyDescriptor):
+ * runtime/JSString.h:
+ (JSC::jsSingleCharacterSubstring):
+ (JSC::JSString::getIndex):
+ (JSC::jsSingleCharacterString):
+ (JSC::JSString::getStringPropertySlot):
+ * runtime/UStringImpl.cpp:
+ (JSC::singleCharacterSubstring):
+ * runtime/UStringImpl.h:
+ (JSC::UStringImpl::singleCharacterSubstring):
+
2010-02-19 Oliver Hunt <oliver@apple.com>
RS = Gavin Barraclough.
@@ -196,7 +3857,7 @@
another rope node. A low bit in each pointer is used to distinguish between
rope & string elements, in a fashion similar to the recently-removed
PtrAndFlags class (see https://bugs.webkit.org/show_bug.cgi?id=33731 ). Again,
- this causes a problem for Leaks – refactor to remove the magic pointer
+ this causes a problem for Leaks - refactor to remove the magic pointer
mangling.
Move Rope out from JSString.h and rename to URopeImpl, to match UStringImpl.
@@ -639,6 +4300,40 @@
2010-02-12 Janne Koskinen <janne.p.koskinen@digia.com>
+ Reviewed by Tor Arne Vestbø.
+
+ Additional refptr/passrefptr workarounds for WINSCW compiler
+ https://bugs.webkit.org/show_bug.cgi?id=28054
+
+ * wtf/PassRefPtr.h:
+ (WTF::refIfNotNull):
+ (WTF::PassRefPtr::PassRefPtr):
+ (WTF::PassRefPtr::~PassRefPtr):
+ (WTF::PassRefPtr::clear):
+ (WTF::::operator):
+ * wtf/RefPtr.h:
+ (WTF::RefPtr::RefPtr):
+ (WTF::::operator):
+
+2010-02-12 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Tor Arne Vestbø.
+
+ Additional refptr/passrefptr workarounds for WINSCW compiler
+ https://bugs.webkit.org/show_bug.cgi?id=28054
+
+ * wtf/PassRefPtr.h:
+ (WTF::refIfNotNull):
+ (WTF::PassRefPtr::PassRefPtr):
+ (WTF::PassRefPtr::~PassRefPtr):
+ (WTF::PassRefPtr::clear):
+ (WTF::::operator):
+ * wtf/RefPtr.h:
+ (WTF::RefPtr::RefPtr):
+ (WTF::::operator):
+
+2010-02-12 Janne Koskinen <janne.p.koskinen@digia.com>
+
Reviewed by Simon Hausmann.
Don't import the cmath functions from std:: for WINSCW.
@@ -7672,7 +11367,7 @@ The very last cell in the block is not allocated -- should not be marked.
Fix branchDouble behaviour on ARM THUMB2 JIT.
The ARMv7 JIT is currently using ARMv7Assembler::ConditionEQ to branch
- for DoubleEqualOrUnordered, however this is incorrect – ConditionEQ won't
+ for DoubleEqualOrUnordered, however this is incorrect - ConditionEQ won't
branch on unordered operands. Similarly, DoubleLessThanOrUnordered &
DoubleLessThanOrEqualOrUnordered use ARMv7Assembler::ConditionLO &
ARMv7Assembler::ConditionLS, whereas they should be using
diff --git a/JavaScriptCore/Configurations/Base.xcconfig b/JavaScriptCore/Configurations/Base.xcconfig
index c338eb7..4854b64 100644
--- a/JavaScriptCore/Configurations/Base.xcconfig
+++ b/JavaScriptCore/Configurations/Base.xcconfig
@@ -67,6 +67,8 @@ REAL_PLATFORM_NAME_iphoneos = iphoneos;
REAL_PLATFORM_NAME_iphonesimulator = iphonesimulator;
REAL_PLATFORM_NAME_macosx = macosx;
+TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR);
+
// DEBUG_DEFINES, GCC_OPTIMIZATION_LEVEL, STRIP_INSTALLED_PRODUCT and DEAD_CODE_STRIPPING vary between the debug and normal variants.
// We set up the values for each variant here, and have the Debug configuration in the Xcode project use the _debug variant.
@@ -92,16 +94,36 @@ SECTORDER_FLAGS = -sectorder __TEXT __text JavaScriptCore.order;
// Note that Xcode versions as new as 3.1.2 use XCODE_VERSION_ACTUAL for the minor version
// number. Newer versions of Xcode use XCODE_VERSION_MINOR for the minor version, and
// XCODE_VERSION_ACTUAL for the full version number.
-GCC_VERSION = $(GCC_VERSION_$(XCODE_VERSION_MINOR));
-GCC_VERSION_ = $(GCC_VERSION_$(XCODE_VERSION_ACTUAL));
-GCC_VERSION_0310 = 4.2;
+TARGET_GCC_VERSION = $(TARGET_GCC_VERSION_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+TARGET_GCC_VERSION_ = $(TARGET_GCC_VERSION_1040);
+TARGET_GCC_VERSION_1040 = GCC_40;
+TARGET_GCC_VERSION_1050 = $(TARGET_GCC_VERSION_1050_$(XCODE_VERSION_MINOR));
+TARGET_GCC_VERSION_1050_ = $(TARGET_GCC_VERSION_1050_$(XCODE_VERSION_ACTUAL));
+TARGET_GCC_VERSION_1050_0310 = GCC_42;
+TARGET_GCC_VERSION_1050_0320 = GCC_42;
+TARGET_GCC_VERSION_1060 = GCC_42;
+TARGET_GCC_VERSION_1070 = LLVM_GCC_42;
+
+GCC_VERSION = $(GCC_VERSION_$(TARGET_GCC_VERSION));
+GCC_VERSION_GCC_40 = 4.0;
+GCC_VERSION_GCC_42 = 4.2;
+GCC_VERSION_LLVM_GCC_42 = com.apple.compilers.llvmgcc42;
+
+// If the target Mac OS X version does not match the current Mac OS X version then we'll want to build using the target version's SDK.
+SDKROOT = $(SDKROOT_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR));
+SDKROOT_1050_1040 = macosx10.4;
+SDKROOT_1060_1040 = macosx10.4;
+SDKROOT_1060_1050 = macosx10.5;
+SDKROOT_1070_1040 = macosx10.4;
+SDKROOT_1070_1050 = macosx10.5;
+SDKROOT_1070_1060 = macosx10.6;
// HAVE_DTRACE is disabled on Leopard due to <rdar://problem/5628149>
HAVE_DTRACE = $(HAVE_DTRACE_$(REAL_PLATFORM_NAME));
HAVE_DTRACE_iphoneos = 1;
HAVE_DTRACE_iphonesimulator = 0;
-HAVE_DTRACE_macosx = $(HAVE_DTRACE_macosx_$(MAC_OS_X_VERSION_MAJOR));
+HAVE_DTRACE_macosx = $(HAVE_DTRACE_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
HAVE_DTRACE_macosx_ = $(HAVE_DTRACE_macosx_1040);
HAVE_DTRACE_macosx_1040 = 0;
HAVE_DTRACE_macosx_1050 = 0;
diff --git a/JavaScriptCore/Configurations/DebugRelease.xcconfig b/JavaScriptCore/Configurations/DebugRelease.xcconfig
index cbb0c8b..1e981f8 100644
--- a/JavaScriptCore/Configurations/DebugRelease.xcconfig
+++ b/JavaScriptCore/Configurations/DebugRelease.xcconfig
@@ -26,7 +26,7 @@
ARCHS = $(ARCHS_$(REAL_PLATFORM_NAME));
ARCHS_iphoneos = $(ARCHS_UNIVERSAL_IPHONE_OS);
ARCHS_iphonesimulator = $(NATIVE_ARCH);
-ARCHS_macosx = $(ARCHS_macosx_$(MAC_OS_X_VERSION_MAJOR));
+ARCHS_macosx = $(ARCHS_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR));
ARCHS_macosx_ = $(ARCHS_macosx_1040);
ARCHS_macosx_1040 = $(NATIVE_ARCH);
ARCHS_macosx_1050 = $(NATIVE_ARCH);
@@ -35,7 +35,7 @@ ARCHS_macosx_1070 = $(ARCHS_STANDARD_32_64_BIT);
ONLY_ACTIVE_ARCH = YES;
-MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(MAC_OS_X_VERSION_MAJOR));
+MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR));
MACOSX_DEPLOYMENT_TARGET_ = 10.4;
MACOSX_DEPLOYMENT_TARGET_1040 = 10.4;
MACOSX_DEPLOYMENT_TARGET_1050 = 10.5;
diff --git a/JavaScriptCore/Configurations/FeatureDefines.xcconfig b/JavaScriptCore/Configurations/FeatureDefines.xcconfig
index 8343ce7..881c788 100644
--- a/JavaScriptCore/Configurations/FeatureDefines.xcconfig
+++ b/JavaScriptCore/Configurations/FeatureDefines.xcconfig
@@ -31,16 +31,17 @@
// Set any ENABLE_FEATURE_NAME macro to an empty string to disable that feature.
-ENABLE_3D_CANVAS = $(ENABLE_3D_CANVAS_$(MAC_OS_X_VERSION_MAJOR));
+ENABLE_3D_CANVAS = $(ENABLE_3D_CANVAS_$(TARGET_MAC_OS_X_VERSION_MAJOR));
ENABLE_3D_CANVAS_1050 = ENABLE_3D_CANVAS;
ENABLE_3D_CANVAS_1060 = ENABLE_3D_CANVAS;
ENABLE_3D_CANVAS_1070 = ENABLE_3D_CANVAS;
-ENABLE_3D_RENDERING = $(ENABLE_3D_RENDERING_$(MAC_OS_X_VERSION_MAJOR));
+ENABLE_3D_RENDERING = $(ENABLE_3D_RENDERING_$(TARGET_MAC_OS_X_VERSION_MAJOR));
ENABLE_3D_RENDERING_1050 = ENABLE_3D_RENDERING;
ENABLE_3D_RENDERING_1060 = ENABLE_3D_RENDERING;
ENABLE_3D_RENDERING_1070 = ENABLE_3D_RENDERING;
+ENABLE_BLOB_SLICE = ENABLE_BLOB_SLICE;
ENABLE_CHANNEL_MESSAGING = ENABLE_CHANNEL_MESSAGING;
ENABLE_CLIENT_BASED_GEOLOCATION = ENABLE_CLIENT_BASED_GEOLOCATION;
ENABLE_DATABASE = ENABLE_DATABASE;
@@ -49,6 +50,8 @@ ENABLE_DATALIST = ENABLE_DATALIST;
ENABLE_DOM_STORAGE = ENABLE_DOM_STORAGE;
ENABLE_EVENTSOURCE = ENABLE_EVENTSOURCE;
ENABLE_FILTERS = ENABLE_FILTERS;
+ENABLE_FILE_READER = ;
+ENABLE_FILE_WRITER = ;
ENABLE_GEOLOCATION = ENABLE_GEOLOCATION;
ENABLE_ICONDATABASE = ENABLE_ICONDATABASE;
ENABLE_INDEXED_DATABASE = ;
@@ -56,7 +59,9 @@ ENABLE_JAVASCRIPT_DEBUGGER = ENABLE_JAVASCRIPT_DEBUGGER;
ENABLE_MATHML = ;
ENABLE_NOTIFICATIONS = ;
ENABLE_OFFLINE_WEB_APPLICATIONS = ENABLE_OFFLINE_WEB_APPLICATIONS;
+ENABLE_PROGRESS_TAG = ENABLE_PROGRESS_TAG;
ENABLE_RUBY = ENABLE_RUBY;
+ENABLE_SANDBOX = ENABLE_SANDBOX;
ENABLE_SHARED_WORKERS = ENABLE_SHARED_WORKERS;
ENABLE_SVG = ENABLE_SVG;
ENABLE_SVG_ANIMATION = ENABLE_SVG_ANIMATION;
@@ -73,4 +78,4 @@ ENABLE_XHTMLMP = ;
ENABLE_XPATH = ENABLE_XPATH;
ENABLE_XSLT = ENABLE_XSLT;
-FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_RUBY) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_3D_CANVAS) $(ENABLE_3D_RENDERING) $(ENABLE_BLOB_SLICE) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATAGRID) $(ENABLE_DATALIST) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_FILE_READER) $(ENABLE_FILE_WRITER) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PROGRESS_TAG) $(ENABLE_RUBY) $(ENABLE_SANDBOX) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_VIDEO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WML) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
diff --git a/JavaScriptCore/Configurations/JavaScriptCore.xcconfig b/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
index f8d6c2c..b6ba560 100644
--- a/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
+++ b/JavaScriptCore/Configurations/JavaScriptCore.xcconfig
@@ -44,8 +44,7 @@ INSTALL_PATH = $(SYSTEM_LIBRARY_DIR)/Frameworks;
PRODUCT_NAME = JavaScriptCore;
OTHER_CFLAGS = $(OTHER_CFLAGS_$(CONFIGURATION)_$(CURRENT_VARIANT));
-OTHER_CFLAGS_Release_normal = $(OTHER_CFLAGS_normal_$(XCODE_VERSION_ACTUAL));
-OTHER_CFLAGS_Production_normal = $(OTHER_CFLAGS_normal_$(XCODE_VERSION_ACTUAL));
-OTHER_CFLAGS_normal_0310 = $(OTHER_CFLAGS_normal_GCC_42);
-OTHER_CFLAGS_normal_0320 = $(OTHER_CFLAGS_normal_GCC_42);
+OTHER_CFLAGS_Release_normal = $(OTHER_CFLAGS_normal_$(TARGET_GCC_VERSION));
+OTHER_CFLAGS_Production_normal = $(OTHER_CFLAGS_normal_$(TARGET_GCC_VERSION));
OTHER_CFLAGS_normal_GCC_42 = -fomit-frame-pointer -funwind-tables;
+OTHER_CFLAGS_normal_LLVM_GCC_42 = $(OTHER_CFLAGS_normal_GCC_42);
diff --git a/JavaScriptCore/Configurations/Version.xcconfig b/JavaScriptCore/Configurations/Version.xcconfig
index 0e289b1..6aeb263 100644
--- a/JavaScriptCore/Configurations/Version.xcconfig
+++ b/JavaScriptCore/Configurations/Version.xcconfig
@@ -22,7 +22,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MAJOR_VERSION = 533;
-MINOR_VERSION = 1;
+MINOR_VERSION = 6;
TINY_VERSION = 0;
FULL_VERSION = $(MAJOR_VERSION).$(MINOR_VERSION);
@@ -31,7 +31,7 @@ BUNDLE_VERSION = $(BUNDLE_VERSION_$(CONFIGURATION));
SHORT_VERSION_STRING = $(SHORT_VERSION_STRING_$(CONFIGURATION))
// The system version prefix is based on the current system version.
-SYSTEM_VERSION_PREFIX = $(SYSTEM_VERSION_PREFIX_$(MAC_OS_X_VERSION_MAJOR));
+SYSTEM_VERSION_PREFIX = $(SYSTEM_VERSION_PREFIX_$(TARGET_MAC_OS_X_VERSION_MAJOR));
SYSTEM_VERSION_PREFIX_ = 4; // Some Tiger versions of Xcode don't set MAC_OS_X_VERSION_MAJOR.
SYSTEM_VERSION_PREFIX_1040 = 4;
SYSTEM_VERSION_PREFIX_1050 = 5;
diff --git a/JavaScriptCore/DerivedSources.make b/JavaScriptCore/DerivedSources.make
index 9eaccab..4fc9cad 100644
--- a/JavaScriptCore/DerivedSources.make
+++ b/JavaScriptCore/DerivedSources.make
@@ -48,6 +48,7 @@ all : \
RegExpObject.lut.h \
StringPrototype.lut.h \
docs/bytecode.html \
+ RegExpJitTables.h \
#
# lookup tables for classes
@@ -74,3 +75,7 @@ chartables.c : dftables
docs/bytecode.html: make-bytecode-docs.pl Interpreter.cpp
perl $^ $@
+
+#character tables for Yarr
+RegExpJitTables.h: create_regex_tables
+ python $^ > $@
diff --git a/JavaScriptCore/DerivedSources.pro b/JavaScriptCore/DerivedSources.pro
index 28a229d..7c5aad8 100644
--- a/JavaScriptCore/DerivedSources.pro
+++ b/JavaScriptCore/DerivedSources.pro
@@ -78,7 +78,7 @@ addExtraCompiler(jscbison)
# 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_jit_stubs
-rvctstubs.commands = perl $$rvctstubs.wkScript --prefix RVCT ${QMAKE_FILE_NAME} -i > ${QMAKE_FILE_OUT}
+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
@@ -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)
+#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)
diff --git a/JavaScriptCore/GNUmakefile.am b/JavaScriptCore/GNUmakefile.am
index 53e3c65..2d024c1 100644
--- a/JavaScriptCore/GNUmakefile.am
+++ b/JavaScriptCore/GNUmakefile.am
@@ -10,11 +10,13 @@ javascriptcore_cppflags += \
-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/wtf \
+ -I$(srcdir)/JavaScriptCore/wtf/text \
-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
@@ -33,6 +35,7 @@ javascriptcore_h_api += \
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 \
@@ -210,19 +213,12 @@ javascriptcore_sources += \
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/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 \
@@ -264,7 +260,6 @@ javascriptcore_sources += \
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 \
@@ -275,6 +270,7 @@ javascriptcore_sources += \
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 \
@@ -293,12 +289,24 @@ javascriptcore_sources += \
JavaScriptCore/wtf/ValueCheck.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/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/WTFString.cpp \
+ JavaScriptCore/wtf/text/WTFString.h \
JavaScriptCore/wtf/unicode/Collator.h \
JavaScriptCore/wtf/unicode/CollatorDefault.cpp \
JavaScriptCore/wtf/unicode/UTF8.cpp \
@@ -494,6 +502,8 @@ javascriptcore_sources += \
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 \
@@ -508,7 +518,6 @@ javascriptcore_sources += \
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 \
@@ -538,6 +547,9 @@ DerivedSources/Lexer.lut.h: $(CREATE_HASH_TABLE) $(srcdir)/JavaScriptCore/parser
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) $^ $@
@@ -598,6 +610,7 @@ Programs_jsc_LDADD = \
javascriptcore_dist += \
$(CREATE_HASH_TABLE) \
+ $(CREATE_REGEXP_TABLES) \
JavaScriptCore/AUTHORS \
JavaScriptCore/COPYING.LIB \
JavaScriptCore/ChangeLog \
diff --git a/JavaScriptCore/JavaScriptCore.exp b/JavaScriptCore/JavaScriptCore.exp
index 9355321..e8e34ee 100644
--- a/JavaScriptCore/JavaScriptCore.exp
+++ b/JavaScriptCore/JavaScriptCore.exp
@@ -18,8 +18,10 @@ _JSGlobalContextRetain
_JSObjectCallAsConstructor
_JSObjectCallAsFunction
_JSObjectCopyPropertyNames
+_JSObjectDeletePrivateProperty
_JSObjectDeleteProperty
_JSObjectGetPrivate
+_JSObjectGetPrivateProperty
_JSObjectGetProperty
_JSObjectGetPropertyAtIndex
_JSObjectGetPrototype
@@ -35,6 +37,7 @@ _JSObjectMakeFunction
_JSObjectMakeFunctionWithCallback
_JSObjectMakeRegExp
_JSObjectSetPrivate
+_JSObjectSetPrivateProperty
_JSObjectSetProperty
_JSObjectSetPropertyAtIndex
_JSObjectSetPrototype
@@ -57,6 +60,7 @@ _JSStringIsEqual
_JSStringIsEqualToUTF8CString
_JSStringRelease
_JSStringRetain
+_JSValueCreateJSONString
_JSValueGetType
_JSValueIsBoolean
_JSValueIsEqual
@@ -69,6 +73,7 @@ _JSValueIsStrictEqual
_JSValueIsString
_JSValueIsUndefined
_JSValueMakeBoolean
+_JSValueMakeFromJSONString
_JSValueMakeNull
_JSValueMakeNumber
_JSValueMakeString
@@ -79,6 +84,10 @@ _JSValueToNumber
_JSValueToObject
_JSValueToStringCopy
_JSValueUnprotect
+_JSWeakObjectMapClear
+_JSWeakObjectMapCreate
+_JSWeakObjectMapGet
+_JSWeakObjectMapSet
_WTFLog
_WTFLogVerbose
_WTFReportArgumentAssertionFailure
@@ -90,12 +99,14 @@ __Z12jsRegExpFreeP8JSRegExp
__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
-__ZN3JSC10Identifier5equalEPKNS_11UStringImplEPKc
+__ZN3JSC10Identifier4fromEPNS_9ExecStateEi
+__ZN3JSC10Identifier4fromEPNS_9ExecStateEj
+__ZN3JSC10Identifier5equalEPKN7WebCore10StringImplEPKc
__ZN3JSC10JSFunctionC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEiRKNS_10IdentifierEPFNS_7JSValueES2_PNS_8JSObjectESA_RKNS_7ArgListEE
__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeE
__ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeEPKc
@@ -103,23 +114,20 @@ __ZN3JSC10throwErrorEPNS_9ExecStateENS_9ErrorTypeERKNS_7UStringE
__ZN3JSC11JSByteArray15createStructureENS_7JSValueE
__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEPNS3_9ByteArrayEPKNS_9ClassInfoE
__ZN3JSC11ParserArena5resetEv
-__ZN3JSC11UStringImpl12sharedBufferEv
-__ZN3JSC11UStringImpl7s_emptyE
-__ZN3JSC11UStringImplD1Ev
__ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
__ZN3JSC12DateInstance4infoE
__ZN3JSC12DateInstanceC1EPNS_9ExecStateEN3WTF17NonNullPassRefPtrINS_9StructureEEEd
__ZN3JSC12DateInstanceC1EPNS_9ExecStateEd
__ZN3JSC12JSGlobalData10ClientDataD2Ev
__ZN3JSC12JSGlobalData11jsArrayVPtrE
-__ZN3JSC12JSGlobalData12createLeakedEv
+__ZN3JSC12JSGlobalData12createLeakedENS_15ThreadStackTypeE
__ZN3JSC12JSGlobalData12jsStringVPtrE
__ZN3JSC12JSGlobalData12stopSamplingEv
__ZN3JSC12JSGlobalData13startSamplingEv
__ZN3JSC12JSGlobalData14dumpSampleDataEPNS_9ExecStateE
__ZN3JSC12JSGlobalData14resetDateCacheEv
__ZN3JSC12JSGlobalData14sharedInstanceEv
-__ZN3JSC12JSGlobalData6createEv
+__ZN3JSC12JSGlobalData6createENS_15ThreadStackTypeE
__ZN3JSC12JSGlobalDataD1Ev
__ZN3JSC12SamplingTool5setupEv
__ZN3JSC12SmallStrings17createEmptyStringEPNS_12JSGlobalDataE
@@ -163,7 +171,7 @@ __ZN3JSC16JSVariableObject14symbolTableGetERKNS_10IdentifierERNS_18PropertyDescr
__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
@@ -184,8 +192,6 @@ __ZN3JSC23objectProtoFuncToStringEPNS_9ExecStateEPNS_8JSObjectENS_7JSValueERKNS_
__ZN3JSC23setUpStaticFunctionSlotEPNS_9ExecStateEPKNS_9HashEntryEPNS_8JSObjectERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC24createStackOverflowErrorEPNS_9ExecStateE
__ZN3JSC25evaluateInGlobalCallFrameERKNS_7UStringERNS_7JSValueEPNS_14JSGlobalObjectE
-__ZN3JSC25g_identifierTableSpecificE
-__ZN3JSC29createIdentifierTableSpecificEv
__ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
__ZN3JSC3NaNE
__ZN3JSC4Heap14primaryHeapEndEv
@@ -203,12 +209,10 @@ __ZN3JSC4Heap7protectENS_7JSValueE
__ZN3JSC4Heap8allocateEm
__ZN3JSC4Heap9unprotectENS_7JSValueE
__ZN3JSC4callEPNS_9ExecStateENS_7JSValueENS_8CallTypeERKNS_8CallDataES2_RKNS_7ArgListE
-__ZN3JSC5equalEPKNS_11UStringImplES2_
__ZN3JSC6JSCell11getCallDataERNS_8CallDataE
__ZN3JSC6JSCell11getJSNumberEv
__ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateERKNS_10IdentifierE
__ZN3JSC6JSCell14deletePropertyEPNS_9ExecStateEj
-__ZN3JSC6JSCell14toThisJSStringEPNS_9ExecStateE
__ZN3JSC6JSCell16getConstructDataERNS_13ConstructDataE
__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateERKNS_10IdentifierERNS_12PropertySlotE
__ZN3JSC6JSCell18getOwnPropertySlotEPNS_9ExecStateEjRNS_12PropertySlotE
@@ -224,12 +228,14 @@ __ZN3JSC6JSLock6unlockENS_14JSLockBehaviorE
__ZN3JSC6JSLock9lockCountEv
__ZN3JSC6JSLockC1EPNS_9ExecStateE
__ZN3JSC6Parser5parseEPNS_12JSGlobalDataEPiPNS_7UStringE
-__ZN3JSC7CStringD1Ev
-__ZN3JSC7CStringaSERKS0_
+__ZN3JSC7JSArray12markChildrenERNS_9MarkStackE
+__ZN3JSC7JSArray15setSubclassDataEPv
__ZN3JSC7JSArray4infoE
__ZN3JSC7JSArray9setLengthEj
__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEE
__ZN3JSC7JSArrayC1EN3WTF17NonNullPassRefPtrINS_9StructureEEERKNS_7ArgListE
+__ZN3JSC7JSArrayC2EN3WTF17NonNullPassRefPtrINS_9StructureEEE
+__ZN3JSC7JSArrayD2Ev
__ZN3JSC7Profile10restoreAllEv
__ZN3JSC7Profile5focusEPKNS_11ProfileNodeE
__ZN3JSC7Profile7excludeEPKNS_11ProfileNodeE
@@ -238,7 +244,6 @@ __ZN3JSC7UString4fromEd
__ZN3JSC7UString4fromEi
__ZN3JSC7UString4fromEj
__ZN3JSC7UString4fromEl
-__ZN3JSC7UString9s_nullRepE
__ZN3JSC7UStringC1EPKc
__ZN3JSC7UStringC1EPKtj
__ZN3JSC8Debugger23recompileAllJSFunctionsEPNS_12JSGlobalDataE
@@ -280,7 +285,7 @@ __ZN3JSC9MarkStack10s_pageSizeE
__ZN3JSC9MarkStack12releaseStackEPvm
__ZN3JSC9MarkStack13allocateStackEm
__ZN3JSC9MarkStack18initializePagesizeEv
-__ZN3JSC9Structure13hasTransitionEPNS_11UStringImplEj
+__ZN3JSC9Structure13hasTransitionEPN7WebCore10StringImplEj
__ZN3JSC9Structure17stopIgnoringLeaksEv
__ZN3JSC9Structure18startIgnoringLeaksEv
__ZN3JSC9Structure21addPropertyTransitionEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
@@ -289,7 +294,7 @@ __ZN3JSC9Structure25changePrototypeTransitionEPS0_NS_7JSValueE
__ZN3JSC9Structure27despecifyDictionaryFunctionERKNS_10IdentifierE
__ZN3JSC9Structure27despecifyFunctionTransitionEPS0_RKNS_10IdentifierE
__ZN3JSC9Structure28addPropertyWithoutTransitionERKNS_10IdentifierEjPNS_6JSCellE
-__ZN3JSC9Structure3getEPKNS_11UStringImplERjRPNS_6JSCellE
+__ZN3JSC9Structure3getEPKN7WebCore10StringImplERjRPNS_6JSCellE
__ZN3JSC9Structure40addPropertyTransitionToExistingStructureEPS0_RKNS_10IdentifierEjPNS_6JSCellERm
__ZN3JSC9StructureC1ENS_7JSValueERKNS_8TypeInfoEj
__ZN3JSC9StructureD1Ev
@@ -307,9 +312,13 @@ __ZN3WTF12createThreadEPFPvS0_ES0_PKc
__ZN3WTF12detachThreadEj
__ZN3WTF12isMainThreadEv
__ZN3WTF12randomNumberEv
+__ZN3WTF13WTFThreadData10staticDataE
+__ZN3WTF13WTFThreadDataC1Ev
+__ZN3WTF13WTFThreadDataD1Ev
__ZN3WTF13currentThreadEv
__ZN3WTF13tryFastCallocEmm
__ZN3WTF13tryFastMallocEm
+__ZN3WTF14fastMallocSizeEPKv
__ZN3WTF15ThreadCondition4waitERNS_5MutexE
__ZN3WTF15ThreadCondition6signalEv
__ZN3WTF15ThreadCondition9broadcastEv
@@ -343,7 +352,12 @@ __ZN3WTF5Mutex7tryLockEv
__ZN3WTF5MutexC1Ev
__ZN3WTF5MutexD1Ev
__ZN3WTF6strtodEPKcPPc
+__ZN3WTF7CString11mutableDataEv
+__ZN3WTF7CString16newUninitializedEmRPc
+__ZN3WTF7CStringC1EPKc
+__ZN3WTF7CStringC1EPKcj
__ZN3WTF7Unicode18convertUTF16ToUTF8EPPKtS2_PPcS4_b
+__ZN3WTF7Unicode18convertUTF8ToUTF16EPPKcS2_PPtS4_b
__ZN3WTF8Collator18setOrderLowerFirstEb
__ZN3WTF8CollatorC1EPKc
__ZN3WTF8CollatorD1Ev
@@ -351,9 +365,93 @@ __ZN3WTF8fastFreeEPv
__ZN3WTF8msToYearEd
__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
+__ZN7WebCore10StringImpl6secureEt
+__ZN7WebCore10StringImpl7replaceEPS0_S1_
+__ZN7WebCore10StringImpl7replaceEjjPS0_
+__ZN7WebCore10StringImpl7replaceEtPS0_
+__ZN7WebCore10StringImpl7replaceEtt
+__ZN7WebCore10StringImpl8endsWithEPS0_b
+__ZN7WebCore10StringImpl9substringEjj
+__ZN7WebCore10StringImplD1Ev
+__ZN7WebCore11commentAtomE
+__ZN7WebCore12AtomicString3addEPKc
+__ZN7WebCore12AtomicString3addEPKt
+__ZN7WebCore12AtomicString3addEPKtj
+__ZN7WebCore12AtomicString3addEPKtjj
+__ZN7WebCore12AtomicString3addEPNS_10StringImplE
+__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
+__ZN7WebCore6StringC1EPKc
+__ZN7WebCore6StringC1EPKcj
+__ZN7WebCore6StringC1EPKt
+__ZN7WebCore6StringC1EPKtj
+__ZN7WebCore7xmlAtomE
+__ZN7WebCore8nullAtomE
+__ZN7WebCore8starAtomE
+__ZN7WebCore8textAtomE
+__ZN7WebCore9emptyAtomE
+__ZN7WebCore9xmlnsAtomE
+__ZN7WebCoreeqERKNS_12AtomicStringEPKc
+__ZN7WebCoreplEPKcRKNS_6StringE
+__ZN7WebCoreplERKNS_6StringEPKc
+__ZN7WebCoreplERKNS_6StringES2_
__ZNK3JSC10JSFunction23isHostFunctionNonInlineEv
__ZNK3JSC11Interpreter14retrieveCallerEPNS_9ExecStateEPNS_16InternalFunctionE
__ZNK3JSC11Interpreter18retrieveLastCallerEPNS_9ExecStateERiRlRNS_7UStringERNS_7JSValueE
+__ZNK3JSC12PropertySlot14functionGetterEPNS_9ExecStateE
__ZNK3JSC14JSGlobalObject14isDynamicScopeEv
__ZNK3JSC16InternalFunction9classInfoEv
__ZNK3JSC16JSVariableObject16isVariableObjectEv
@@ -373,7 +471,6 @@ __ZNK3JSC4Heap10statisticsEv
__ZNK3JSC4Heap11objectCountEv
__ZNK3JSC6JSCell11toPrimitiveEPNS_9ExecStateENS_22PreferredPrimitiveTypeE
__ZNK3JSC6JSCell12toThisObjectEPNS_9ExecStateE
-__ZNK3JSC6JSCell12toThisStringEPNS_9ExecStateE
__ZNK3JSC6JSCell14isGetterSetterEv
__ZNK3JSC6JSCell8toNumberEPNS_9ExecStateE
__ZNK3JSC6JSCell8toObjectEPNS_9ExecStateE
@@ -384,6 +481,7 @@ __ZNK3JSC6JSCell9getStringEPNS_9ExecStateERNS_7UStringE
__ZNK3JSC6JSCell9getUInt32ERj
__ZNK3JSC6JSCell9toBooleanEPNS_9ExecStateE
__ZNK3JSC7ArgList8getSliceEiRS0_
+__ZNK3JSC7JSArray12subclassDataEv
__ZNK3JSC7JSValue16toObjectSlowCaseEPNS_9ExecStateE
__ZNK3JSC7JSValue19synthesizePrototypeEPNS_9ExecStateE
__ZNK3JSC7JSValue20toThisObjectSlowCaseEPNS_9ExecStateE
@@ -407,7 +505,39 @@ __ZNK3JSC8JSObject9toBooleanEPNS_9ExecStateE
__ZNK3JSC8JSString11resolveRopeEPNS_9ExecStateE
__ZNK3JSC9HashTable11createTableEPNS_12JSGlobalDataE
__ZNK3JSC9HashTable11deleteTableEv
+__ZNK3WTF7CString4dataEv
+__ZNK3WTF7CString6lengthEv
__ZNK3WTF8Collator7collateEPKtmS2_m
+__ZNK7WebCore12AtomicString5lowerEv
+__ZNK7WebCore6String10charactersEv
+__ZNK7WebCore6String11toIntStrictEPbi
+__ZNK7WebCore6String12toUIntStrictEPbi
+__ZNK7WebCore6String14threadsafeCopyEv
+__ZNK7WebCore6String15stripWhiteSpaceEv
+__ZNK7WebCore6String16removeCharactersEPFbtE
+__ZNK7WebCore6String17crossThreadStringEv
+__ZNK7WebCore6String18simplifyWhiteSpaceEv
+__ZNK7WebCore6String19characterStartingAtEj
+__ZNK7WebCore6String4utf8Ev
+__ZNK7WebCore6String5asciiEv
+__ZNK7WebCore6String5lowerEv
+__ZNK7WebCore6String5splitERKS0_RN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5splitERKS0_bRN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5splitEtRN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5splitEtbRN3WTF6VectorIS0_Lm0EEE
+__ZNK7WebCore6String5toIntEPb
+__ZNK7WebCore6String5upperEv
+__ZNK7WebCore6String6latin1Ev
+__ZNK7WebCore6String6lengthEv
+__ZNK7WebCore6String6toUIntEPb
+__ZNK7WebCore6String7isEmptyEv
+__ZNK7WebCore6String7toFloatEPb
+__ZNK7WebCore6String8foldCaseEv
+__ZNK7WebCore6String8toDoubleEPb
+__ZNK7WebCore6String8toIntPtrEPb
+__ZNK7WebCore6String8toUInt64EPb
+__ZNK7WebCore6String9substringEjj
+__ZNK7WebCore6StringixEj
__ZTVN3JSC12StringObjectE
__ZTVN3JSC14JSGlobalObjectE
__ZTVN3JSC15JSWrapperObjectE
diff --git a/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp b/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
index 66f40e9..b2ccf1a 100644
--- a/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
+++ b/JavaScriptCore/JavaScriptCore.gyp/JavaScriptCore.gyp
@@ -114,7 +114,7 @@
# ... 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', 'wtf/TC.*\\.(cpp|h)$'],
diff --git a/JavaScriptCore/JavaScriptCore.gypi b/JavaScriptCore/JavaScriptCore.gypi
index c0eb086..ad2d09e 100644
--- a/JavaScriptCore/JavaScriptCore.gypi
+++ b/JavaScriptCore/JavaScriptCore.gypi
@@ -325,26 +325,13 @@
'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',
- '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',
@@ -368,8 +355,8 @@
'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',
@@ -409,11 +396,13 @@
'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/qt/StringQt.cpp',
'wtf/qt/ThreadingQt.cpp',
'wtf/TCPageMap.h',
'wtf/TCSpinLock.h',
@@ -430,6 +419,16 @@
'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/WTFString.cpp',
+ 'wtf/text/WTFString.h',
'wtf/unicode/Collator.h',
'wtf/unicode/CollatorDefault.cpp',
'wtf/unicode/glib/UnicodeGLib.cpp',
@@ -446,6 +445,8 @@
'wtf/Vector.h',
'wtf/VectorTraits.h',
'wtf/VMTags.h',
+ 'wtf/WTFThreadData.cpp',
+ 'wtf/WTFThreadData.h',
'wtf/win/MainThreadWin.cpp',
'wtf/wx/MainThreadWx.cpp',
'yarr/RegexCompiler.cpp',
diff --git a/JavaScriptCore/JavaScriptCore.pri b/JavaScriptCore/JavaScriptCore.pri
index d4cfe10..24c8ce5 100644
--- a/JavaScriptCore/JavaScriptCore.pri
+++ b/JavaScriptCore/JavaScriptCore.pri
@@ -1,5 +1,6 @@
# JavaScriptCore - Qt4 build info
VPATH += $$PWD
+JAVASCRIPTCORE_TARGET = jscore
CONFIG(standalone_package) {
isEmpty(JSC_GENERATED_SOURCES_DIR):JSC_GENERATED_SOURCES_DIR = $$PWD/generated
@@ -7,15 +8,12 @@ CONFIG(standalone_package) {
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"
+ LIBS += -lhal
}
INCLUDEPATH = \
@@ -31,8 +29,8 @@ INCLUDEPATH = \
$$PWD/pcre \
$$PWD/profiler \
$$PWD/runtime \
- $$PWD/wrec \
$$PWD/wtf \
+ $$PWD/wtf/symbian \
$$PWD/wtf/unicode \
$$PWD/yarr \
$$PWD/API \
@@ -40,11 +38,10 @@ INCLUDEPATH = \
$$JSC_GENERATED_SOURCES_DIR \
$$INCLUDEPATH
+win32-*: DEFINES += _HAS_TR1=0
+
DEFINES += BUILDING_QT__ BUILDING_JavaScriptCore BUILDING_WTF
-win32-* {
- LIBS += -lwinmm
-}
contains(JAVASCRIPTCORE_JIT,yes) {
DEFINES+=ENABLE_JIT=1
DEFINES+=ENABLE_YARR_JIT=1
@@ -56,177 +53,48 @@ contains(JAVASCRIPTCORE_JIT,no) {
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
- SOURCES += $$QT_SOURCE_TREE/src/3rdparty/ce-compat/ce_time.c
DEFINES += WINCEBASIC
-}
-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/JITPropertyAccess32_64.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
-
-# Generated files, simply list them for JavaScriptCore
-SOURCES += \
- $${JSC_GENERATED_SOURCES_DIR}/Grammar.cpp
-
-!contains(DEFINES, USE_SYSTEM_MALLOC) {
- SOURCES += wtf/TCSystemAlloc.cpp
+ INCLUDEPATH += $$PWD/../JavaScriptCore/os-wince
+ INCLUDEPATH += $$PWD/../JavaScriptCore/os-win32
}
+
+defineTest(addJavaScriptCoreLib) {
+ pathToJavaScriptCoreOutput = $$ARGS
+ CONFIG(debug_and_release):CONFIG(debug, debug|release): pathToJavaScriptCoreOutput = $$pathToJavaScriptCoreOutput/debug
+ CONFIG(debug_and_release):CONFIG(release, debug|release): pathToJavaScriptCoreOutput = $$pathToJavaScriptCoreOutput/release
+
+ 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
+ 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
+ }
+
+ 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)
+}
diff --git a/JavaScriptCore/JavaScriptCore.pro b/JavaScriptCore/JavaScriptCore.pro
index 0d6becb..f33be05 100644
--- a/JavaScriptCore/JavaScriptCore.pro
+++ b/JavaScriptCore/JavaScriptCore.pro
@@ -1,28 +1,21 @@
# JavaScriptCore - qmake build info
CONFIG += building-libs
include($$PWD/../WebKit.pri)
+include(JavaScriptCore.pri)
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
+QT += core
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(debug_and_release):CONFIG(debug, debug|release): DESTDIR = debug
+CONFIG(debug_and_release):CONFIG(release, debug|release): DESTDIR = release
!CONFIG(QTDIR_build) {
CONFIG(debug, debug|release) {
@@ -30,20 +23,16 @@ INCLUDEPATH += $$GENERATED_SOURCES_DIR
} 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
+CONFIG(QTDIR_build) {
+ # Remove the following 2 lines if you want debug information in JavaScriptCore
+ CONFIG -= separate_debug_info
+ CONFIG += no_debug_info
}
-linux-*: DEFINES += HAVE_STDINT_H
-freebsd-*: DEFINES += HAVE_PTHREAD_NP_H
-
-DEFINES += BUILD_WEBKIT
-
-win32-*: DEFINES += _HAS_TR1=0
-
# Pick up 3rdparty libraries from INCLUDE/LIB just like with MSVC
win32-g++ {
TMPPATH = $$quote($$(INCLUDE))
@@ -52,11 +41,185 @@ win32-g++ {
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/JITCall.cpp \
+ jit/JIT.cpp \
+ jit/JITOpcodes.cpp \
+ jit/JITPropertyAccess.cpp \
+ jit/JITPropertyAccess32_64.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/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/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/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
+}
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
index 9e1e74a..76f2fa7 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
@@ -1,5 +1,7 @@
EXPORTS
-
+
+ ??0CString@WTF@@QAE@PBD@Z
+ ??0CString@WTF@@QAE@PBDI@Z
??0Collator@WTF@@QAE@PBD@Z
??0DateInstance@JSC@@QAE@PAVExecState@1@N@Z
??0DateInstance@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@N@Z
@@ -13,12 +15,16 @@ EXPORTS
??0PrototypeFunction@JSC@@QAE@PAVExecState@1@HABVIdentifier@1@P6I?AVJSValue@1@0PAVJSObject@1@V41@ABVArgList@1@@Z@Z
??0PrototypeFunction@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@HABVIdentifier@1@P6I?AVJSValue@1@0PAVJSObject@1@V61@ABVArgList@1@@Z@Z
??0RefCountedLeakCounter@WTF@@QAE@PBD@Z
+ ??0String@WebCore@@QAE@PBD@Z
+ ??0String@WebCore@@QAE@PBDI@Z
+ ??0String@WebCore@@QAE@PB_W@Z
+ ??0String@WebCore@@QAE@PB_WI@Z
??0StringObject@JSC@@QAE@PAVExecState@1@V?$NonNullPassRefPtr@VStructure@JSC@@@WTF@@ABVUString@1@@Z
??0Structure@JSC@@AAE@VJSValue@1@ABVTypeInfo@1@I@Z
??0ThreadCondition@WTF@@QAE@XZ
??0UString@JSC@@QAE@PBD@Z
??0UString@JSC@@QAE@PB_WI@Z
- ??1CString@JSC@@QAE@XZ
+ ??0WTFThreadData@WTF@@QAE@XZ
??1ClientData@JSGlobalData@JSC@@UAE@XZ
??1Collator@WTF@@QAE@XZ
??1Debugger@JSC@@UAE@XZ
@@ -27,23 +33,40 @@ EXPORTS
??1JSGlobalObject@JSC@@UAE@XZ
??1Mutex@WTF@@QAE@XZ
??1RefCountedLeakCounter@WTF@@QAE@XZ
+ ??1StringImpl@WebCore@@QAE@XZ
??1Structure@JSC@@QAE@XZ
??1ThreadCondition@WTF@@QAE@XZ
- ??1UStringImpl@JSC@@AAE@XZ
+ ??1WTFThreadData@WTF@@QAE@XZ
??2JSGlobalObject@JSC@@SAPAXIPAVJSGlobalData@1@@Z
??8JSC@@YA_NABVUString@0@0@Z
+ ??8WTF@@YA_NABVCString@0@0@Z
+ ??8WebCore@@YA_NABVAtomicString@0@PBD@Z
+ ??AString@WebCore@@QBE_WI@Z
+ ??HWebCore@@YA?AVString@0@ABV10@0@Z
+ ??HWebCore@@YA?AVString@0@ABV10@PBD@Z
+ ??HWebCore@@YA?AVString@0@PBDABV10@@Z
?NaN@JSC@@3NB
- ?UTF8String@UString@JSC@@QBE?AVCString@2@_N@Z
+ ?UTF8String@UString@JSC@@QBE?AVCString@WTF@@_N@Z
+ ?add@AtomicString@WebCore@@CA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PAVStringImpl@2@@Z
+ ?add@AtomicString@WebCore@@CA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PBD@Z
+ ?add@AtomicString@WebCore@@CA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PB_W@Z
+ ?add@AtomicString@WebCore@@CA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PB_WI@Z
+ ?add@AtomicString@WebCore@@CA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PB_WII@Z
+ ?add@Identifier@JSC@@SA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PAVExecState@2@PBD@Z
+ ?add@PropertyNameArray@JSC@@QAEXPAVStringImpl@WebCore@@@Z
?addPropertyTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z
?addPropertyTransitionToExistingStructure@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@ABVIdentifier@2@IPAVJSCell@2@AAI@Z
?addPropertyWithoutTransition@Structure@JSC@@QAEIABVIdentifier@2@IPAVJSCell@2@@Z
- ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VUStringImpl@JSC@@@WTF@@PAVExecState@2@PAVUStringImpl@2@@Z
- ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VUStringImpl@JSC@@@WTF@@PAVJSGlobalData@2@PAVUStringImpl@2@@Z
- ?add@Identifier@JSC@@SA?AV?$PassRefPtr@VUStringImpl@JSC@@@WTF@@PAVExecState@2@PBD@Z
- ?add@PropertyNameArray@JSC@@QAEXPAVUStringImpl@2@@Z
+ ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PAVExecState@2@PAVStringImpl@WebCore@@@Z
+ ?adopt@StringImpl@WebCore@@SA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@AAVStringBuffer@2@@Z
?allocate@Heap@JSC@@QAEPAXI@Z
?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z
?allocateStack@MarkStack@JSC@@CAPAXI@Z
+ ?append@String@WebCore@@QAEXABV12@@Z
+ ?append@String@WebCore@@QAEXD@Z
+ ?append@String@WebCore@@QAEXPB_WI@Z
+ ?append@String@WebCore@@QAEX_W@Z
+ ?ascii@String@WebCore@@QBE?AV?$Vector@D$0A@@WTF@@XZ
?ascii@UString@JSC@@QBEPADXZ
?attach@Debugger@JSC@@QAEXPAVJSGlobalObject@2@@Z
?broadcast@ThreadCondition@WTF@@QAEXXZ
@@ -52,43 +75,62 @@ EXPORTS
?callOnMainThread@WTF@@YAXP6AXPAX@Z0@Z
?callOnMainThreadAndWait@WTF@@YAXP6AXPAX@Z0@Z
?changePrototypeTransition@Structure@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@PAV12@VJSValue@2@@Z
- ?checkSameIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@PAVUStringImpl@2@@Z
- ?checkSameIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@PAVUStringImpl@2@@Z
+ ?characterStartingAt@String@WebCore@@QBEHI@Z
+ ?characters@String@WebCore@@QBEPB_WXZ
+ ?charactersToDouble@WebCore@@YANPB_WIPA_N@Z
+ ?charactersToFloat@WebCore@@YAMPB_WIPA_N@Z
+ ?charactersToInt@WebCore@@YAHPB_WIPA_N@Z
+ ?charactersToIntStrict@WebCore@@YAHPB_WIPA_NH@Z
+ ?charactersToUIntStrict@WebCore@@YAIPB_WIPA_NH@Z
+ ?charactersWithNullTermination@String@WebCore@@QAEPB_WXZ
+ ?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVExecState@2@@Z
+ ?checkCurrentIdentifierTable@Identifier@JSC@@CAXPAVJSGlobalData@2@@Z
?checkSyntax@JSC@@YA?AVCompletion@1@PAVExecState@1@ABVSourceCode@1@@Z
?classInfo@InternalFunction@JSC@@UBEPBUClassInfo@2@XZ
?classInfo@JSCell@JSC@@UBEPBUClassInfo@2@XZ
?className@JSObject@JSC@@UBE?AVUString@2@XZ
?collate@Collator@WTF@@QBE?AW4Result@12@PB_WI0I@Z
?collectAllGarbage@Heap@JSC@@QAEXXZ
+ ?commentAtom@WebCore@@3VAtomicString@1@B
?configurable@PropertyDescriptor@JSC@@QBE_NXZ
?construct@JSC@@YAPAVJSObject@1@PAVExecState@1@VJSValue@1@W4ConstructType@1@ABTConstructData@1@ABVArgList@1@@Z
?constructArray@JSC@@YAPAVJSArray@1@PAVExecState@1@ABVArgList@1@@Z
?constructEmptyArray@JSC@@YAPAVJSArray@1@PAVExecState@1@@Z
?constructEmptyObject@JSC@@YAPAVJSObject@1@PAVExecState@1@@Z
?constructFunction@JSC@@YAPAVJSObject@1@PAVExecState@1@ABVArgList@1@ABVIdentifier@1@ABVUString@1@H@Z
+ ?containsOnlyWhitespace@StringImpl@WebCore@@QAE_NXZ
?convertUTF16ToUTF8@Unicode@WTF@@YA?AW4ConversionResult@12@PAPB_WPB_WPAPADPAD_N@Z
+ ?convertUTF8ToUTF16@Unicode@WTF@@YA?AW4ConversionResult@12@PAPBDPBDPAPA_WPA_W_N@Z
?create@ByteArray@WTF@@SA?AV?$PassRefPtr@VByteArray@WTF@@@2@I@Z
- ?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@XZ
+ ?create@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@W4ThreadStackType@2@@Z
?create@OpaqueJSString@@SA?AV?$PassRefPtr@UOpaqueJSString@@@WTF@@ABVUString@JSC@@@Z
+ ?create@StringImpl@WebCore@@SA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PBD@Z
+ ?create@StringImpl@WebCore@@SA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PB_WI@Z
+ ?create@StringImpl@WebCore@@SA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PB_WIV?$PassRefPtr@V?$CrossThreadRefCounted@V?$OwnFastMallocPtr@$$CB_W@WTF@@@WTF@@@4@@Z
?createEmptyString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@@Z
?createInheritorID@JSObject@JSC@@AAEPAVStructure@2@XZ
?createInterruptedExecutionException@JSC@@YA?AVJSValue@1@PAVJSGlobalData@1@@Z
- ?createLeaked@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@XZ
+ ?createLeaked@JSGlobalData@JSC@@SA?AV?$PassRefPtr@VJSGlobalData@JSC@@@WTF@@W4ThreadStackType@2@@Z
?createSingleCharacterString@SmallStrings@JSC@@AAEXPAVJSGlobalData@2@E@Z
?createStackOverflowError@JSC@@YA?AVJSValue@1@PAVExecState@1@@Z
+ ?createStrippingNullCharactersSlowCase@StringImpl@WebCore@@CA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PB_WI@Z
?createStructure@JSByteArray@JSC@@SA?AV?$PassRefPtr@VStructure@JSC@@@WTF@@VJSValue@2@@Z
?createTable@HashTable@JSC@@ABEXPAVJSGlobalData@2@@Z
?createThread@WTF@@YAIP6APAXPAX@Z0@Z
?createThread@WTF@@YAIP6APAXPAX@Z0PBD@Z
?createTypeError@JSC@@YA?AVJSValue@1@PAVExecState@1@PBD@Z
+ ?createUninitialized@StringImpl@WebCore@@SA?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@IAAPA_W@Z
+ ?crossThreadString@String@WebCore@@QBE?AV12@XZ
?currentThread@WTF@@YAIXZ
?currentTime@WTF@@YANXZ
+ ?data@CString@WTF@@QBEPBDXZ
?dateToDaysFrom1970@WTF@@YANHHH@Z
?dayInMonthFromDayInYear@WTF@@YAHH_N@Z
?dayInYear@WTF@@YAHNH@Z
?decrement@RefCountedLeakCounter@WTF@@QAEXXZ
?defaultAttributes@PropertyDescriptor@JSC@@0IA
?defaultValue@JSObject@JSC@@UBE?AVJSValue@2@PAVExecState@2@W4PreferredPrimitiveType@2@@Z
+ ?defaultWritingDirection@StringImpl@WebCore@@QAE?AW4Direction@Unicode@WTF@@XZ
?defineGetter@JSGlobalObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@PAVJSObject@2@I@Z
?defineGetter@JSObject@JSC@@UAEXPAVExecState@2@ABVIdentifier@2@PAV12@I@Z
?defineOwnProperty@JSObject@JSC@@UAE_NPAVExecState@2@ABVIdentifier@2@AAVPropertyDescriptor@2@_N@Z
@@ -113,24 +155,47 @@ EXPORTS
?didTimeOut@TimeoutChecker@JSC@@QAE_NPAVExecState@2@@Z
?doubleToStringInJavaScriptFormat@WTF@@YAXNQADPAI@Z
?dumpSampleData@JSGlobalData@JSC@@QAEXPAVExecState@2@@Z
+ ?empty@StringImpl@WebCore@@SAPAV12@XZ
+ ?emptyAtom@WebCore@@3VAtomicString@1@B
+ ?endsWith@StringImpl@WebCore@@QAE_NPAV12@_N@Z
?enumerable@PropertyDescriptor@JSC@@QBE_NXZ
- ?equal@Identifier@JSC@@SA_NPBVUStringImpl@2@PBD@Z
- ?equal@JSC@@YA_NPBVUStringImpl@1@0@Z
+ ?equal@Identifier@JSC@@SA_NPBVStringImpl@WebCore@@PBD@Z
+ ?equal@WebCore@@YA_NPBVStringImpl@1@0@Z
+ ?equal@WebCore@@YA_NPBVStringImpl@1@PBD@Z
+ ?equalIgnoringCase@WebCore@@YA_NPAVStringImpl@1@0@Z
+ ?equalIgnoringCase@WebCore@@YA_NPAVStringImpl@1@PBD@Z
+ ?equalIgnoringCase@WebCore@@YA_NPB_WPBDI@Z
+ ?equalIgnoringNullity@WebCore@@YA_NPAVStringImpl@1@0@Z
?evaluate@DebuggerCallFrame@JSC@@QBE?AVJSValue@2@ABVUString@2@AAV32@@Z
?evaluate@JSC@@YA?AVCompletion@1@PAVExecState@1@AAVScopeChain@1@ABVSourceCode@1@VJSValue@1@@Z
?exclude@Profile@JSC@@QAEXPBVProfileNode@2@@Z
?fastCalloc@WTF@@YAPAXII@Z
?fastFree@WTF@@YAXPAX@Z
?fastMalloc@WTF@@YAPAXI@Z
+ ?fastMallocSize@WTF@@YAIPBX@Z
?fastRealloc@WTF@@YAPAXPAXI@Z
?fastStrDup@WTF@@YAPADPBD@Z
?fastZeroedMalloc@WTF@@YAPAXI@Z
?fillGetterPropertySlot@JSObject@JSC@@QAEXAAVPropertySlot@2@PAVJSValue@2@@Z
+ ?find@AtomicString@WebCore@@SAPAVAtomicStringImpl@2@PB_WII@Z
+ ?find@StringImpl@WebCore@@QAEHP6A_N_W@ZH@Z
+ ?find@StringImpl@WebCore@@QAEHPAV12@H_N@Z
+ ?find@StringImpl@WebCore@@QAEHPBDH_N@Z
+ ?find@StringImpl@WebCore@@QAEH_WH@Z
?focus@Profile@JSC@@QAEXPBVProfileNode@2@@Z
+ ?foldCase@String@WebCore@@QBE?AV12@XZ
+ ?format@String@WebCore@@SA?AV12@PBDZZ
+ ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@H@Z
+ ?from@Identifier@JSC@@SA?AV12@PAVExecState@2@I@Z
?from@UString@JSC@@SA?AV12@H@Z
?from@UString@JSC@@SA?AV12@I@Z
?from@UString@JSC@@SA?AV12@N@Z
+ ?fromUTF8@String@WebCore@@SA?AV12@PBD@Z
+ ?fromUTF8@String@WebCore@@SA?AV12@PBDI@Z
+ ?fromUTF8WithLatin1Fallback@String@WebCore@@SA?AV12@PBDI@Z
+ ?functionGetter@PropertySlot@JSC@@ABE?AVJSValue@2@PAVExecState@2@@Z
?functionName@DebuggerCallFrame@JSC@@QBEPBVUString@2@XZ
+ ?get@Structure@JSC@@QAEIPBVStringImpl@WebCore@@AAIAAPAVJSCell@2@@Z
?getCallData@JSCell@JSC@@UAE?AW4CallType@2@AATCallData@2@@Z
?getConstructData@JSCell@JSC@@UAE?AW4ConstructType@2@AATConstructData@2@@Z
?getJSNumber@JSCell@JSC@@UAE?AVJSValue@2@XZ
@@ -157,25 +222,27 @@ EXPORTS
?getString@JSCell@JSC@@QBE?AVUString@2@PAVExecState@2@@Z
?getString@JSCell@JSC@@QBE_NPAVExecState@2@AAVUString@2@@Z
?getUInt32@JSCell@JSC@@UBE_NAAI@Z
- ?get@Structure@JSC@@QAEIPBVUStringImpl@2@AAIAAPAVJSCell@2@@Z
?getter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
?globalExec@JSGlobalObject@JSC@@UAEPAVExecState@2@XZ
?globalObjectCount@Heap@JSC@@QAEIXZ
?hasInstance@JSObject@JSC@@UAE_NPAVExecState@2@VJSValue@2@1@Z
?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@ABVIdentifier@2@@Z
?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z
- ?hasTransition@Structure@JSC@@QAE_NPAVUStringImpl@2@I@Z
+ ?hasTransition@Structure@JSC@@QAE_NPAVStringImpl@WebCore@@I@Z
?heap@Heap@JSC@@SAPAV12@VJSValue@2@@Z
?increment@RefCountedLeakCounter@WTF@@QAEXXZ
+ ?init@AtomicString@WebCore@@SAXXZ
?init@JSGlobalObject@JSC@@AAEXPAVJSObject@2@@Z
?initializeMainThread@WTF@@YAXXZ
?initializeThreading@JSC@@YAXXZ
?initializeThreading@WTF@@YAXXZ
+ ?insert@String@WebCore@@QAEXABV12@I@Z
?is8Bit@UString@JSC@@QBE_NXZ
?isAccessorDescriptor@PropertyDescriptor@JSC@@QBE_NXZ
?isBusy@Heap@JSC@@QAE_NXZ
?isDataDescriptor@PropertyDescriptor@JSC@@QBE_NXZ
?isDynamicScope@JSGlobalObject@JSC@@UBE_NXZ
+ ?isEmpty@String@WebCore@@QBE_NXZ
?isGetterSetter@JSCell@JSC@@UBE_NXZ
?isHostFunctionNonInline@JSFunction@JSC@@ABE_NXZ
?isMainThread@WTF@@YA_NXZ
@@ -186,11 +253,17 @@ EXPORTS
?jsRegExpExecute@@YAHPBUJSRegExp@@PB_WHHPAHH@Z
?jsRegExpFree@@YAXPAUJSRegExp@@@Z
?jsString@JSC@@YAPAVJSString@1@PAVJSGlobalData@1@ABVUString@1@@Z
+ ?latin1@String@WebCore@@QBE?AVCString@WTF@@XZ
+ ?length@CString@WTF@@QBEIXZ
+ ?length@String@WebCore@@QBEIXZ
?lock@JSLock@JSC@@SAXW4JSLockBehavior@2@@Z
?lock@Mutex@WTF@@QAEXXZ
?lockAtomicallyInitializedStaticMutex@WTF@@YAXXZ
?lookupGetter@JSObject@JSC@@UAE?AVJSValue@2@PAVExecState@2@ABVIdentifier@2@@Z
?lookupSetter@JSObject@JSC@@UAE?AVJSValue@2@PAVExecState@2@ABVIdentifier@2@@Z
+ ?lower@AtomicString@WebCore@@QBE?AV12@XZ
+ ?lower@String@WebCore@@QBE?AV12@XZ
+ ?lower@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@XZ
?markChildren@JSGlobalObject@JSC@@UAEXAAVMarkStack@2@@Z
?markChildren@JSObject@JSC@@UAEXAAVMarkStack@2@@Z
?markChildren@JSWrapperObject@JSC@@EAEXAAVMarkStack@2@@Z
@@ -198,7 +271,17 @@ EXPORTS
?monthFromDayInYear@WTF@@YAHH_N@Z
?msToYear@WTF@@YAHN@Z
?name@InternalFunction@JSC@@QAEABVUString@2@PAVExecState@2@@Z
+ ?newUninitialized@CString@WTF@@SA?AV12@IAAPAD@Z
?nonInlineNaN@JSC@@YANXZ
+ ?nullAtom@WebCore@@3VAtomicString@1@B
+ ?number@String@WebCore@@SA?AV12@G@Z
+ ?number@String@WebCore@@SA?AV12@H@Z
+ ?number@String@WebCore@@SA?AV12@I@Z
+ ?number@String@WebCore@@SA?AV12@J@Z
+ ?number@String@WebCore@@SA?AV12@K@Z
+ ?number@String@WebCore@@SA?AV12@N@Z
+ ?number@String@WebCore@@SA?AV12@_J@Z
+ ?number@String@WebCore@@SA?AV12@_K@Z
?objectCount@Heap@JSC@@QBEIXZ
?objectProtoFuncToString@JSC@@YI?AVJSValue@1@PAVExecState@1@PAVJSObject@1@V21@ABVArgList@1@@Z
?parse@Parser@JSC@@AAEXPAVJSGlobalData@2@PAHPAVUString@2@@Z
@@ -223,6 +306,12 @@ EXPORTS
?recompileAllJSFunctions@Debugger@JSC@@QAEXPAVJSGlobalData@2@@Z
?recordExtraCost@Heap@JSC@@AAEXI@Z
?releaseStack@MarkStack@JSC@@CAXPAXI@Z
+ ?remove@String@WebCore@@QAEXIH@Z
+ ?removeCharacters@String@WebCore@@QBE?AV12@P6A_N_W@Z@Z
+ ?replace@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@IIPAV12@@Z
+ ?replace@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@PAV12@0@Z
+ ?replace@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@_W0@Z
+ ?replace@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@_WPAV12@@Z
?reset@ParserArena@JSC@@QAEXXZ
?reset@TimeoutChecker@JSC@@QAEXXZ
?resetDateCache@JSGlobalData@JSC@@QAEXXZ
@@ -230,6 +319,9 @@ EXPORTS
?restoreAll@Profile@JSC@@QAEXXZ
?retrieveCaller@Interpreter@JSC@@QBE?AVJSValue@2@PAVExecState@2@PAVInternalFunction@2@@Z
?retrieveLastCaller@Interpreter@JSC@@QBEXPAVExecState@2@AAH1AAVUString@2@AAVJSValue@2@@Z
+ ?reverseFind@StringImpl@WebCore@@QAEHPAV12@H_N@Z
+ ?reverseFind@StringImpl@WebCore@@QAEH_WH@Z
+ ?secure@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@_W@Z
?setAccessorDescriptor@PropertyDescriptor@JSC@@QAEXVJSValue@2@0I@Z
?setConfigurable@PropertyDescriptor@JSC@@QAEX_N@Z
?setDescriptor@PropertyDescriptor@JSC@@QAEXVJSValue@2@I@Z
@@ -245,20 +337,33 @@ EXPORTS
?setUpStaticFunctionSlot@JSC@@YAXPAVExecState@1@PBVHashEntry@1@PAVJSObject@1@ABVIdentifier@1@AAVPropertySlot@1@@Z
?setWritable@PropertyDescriptor@JSC@@QAEX_N@Z
?setter@PropertyDescriptor@JSC@@QBE?AVJSValue@2@XZ
- ?sharedBuffer@UStringImpl@JSC@@QAEPAV?$CrossThreadRefCounted@V?$OwnFastMallocPtr@_W@WTF@@@WTF@@XZ
+ ?sharedBuffer@StringImpl@WebCore@@QAEPAV?$CrossThreadRefCounted@V?$OwnFastMallocPtr@$$CB_W@WTF@@@WTF@@XZ
?signal@ThreadCondition@WTF@@QAEXXZ
+ ?simplifyWhiteSpace@String@WebCore@@QBE?AV12@XZ
+ ?simplifyWhiteSpace@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@XZ
?slowAppend@MarkedArgumentBuffer@JSC@@AAEXVJSValue@2@@Z
+ ?split@String@WebCore@@QBEXABV12@AAV?$Vector@VString@WebCore@@$0A@@WTF@@@Z
+ ?split@String@WebCore@@QBEXABV12@_NAAV?$Vector@VString@WebCore@@$0A@@WTF@@@Z
+ ?split@String@WebCore@@QBEX_WAAV?$Vector@VString@WebCore@@$0A@@WTF@@@Z
+ ?split@String@WebCore@@QBEX_W_NAAV?$Vector@VString@WebCore@@$0A@@WTF@@@Z
+ ?starAtom@WebCore@@3VAtomicString@1@B
?startIgnoringLeaks@Structure@JSC@@SAXXZ
?startProfiling@Profiler@JSC@@QAEXPAVExecState@2@ABVUString@2@@Z
?startSampling@JSGlobalData@JSC@@QAEXXZ
+ ?staticData@WTFThreadData@WTF@@0PAV?$ThreadSpecific@VWTFThreadData@WTF@@@2@A
?stopIgnoringLeaks@Structure@JSC@@SAXXZ
?stopProfiling@Profiler@JSC@@QAE?AV?$PassRefPtr@VProfile@JSC@@@WTF@@PAVExecState@2@ABVUString@2@@Z
?stopSampling@JSGlobalData@JSC@@QAEXXZ
+ ?stripWhiteSpace@String@WebCore@@QBE?AV12@XZ
?strtod@WTF@@YANPBDPAPAD@Z
?substr@UString@JSC@@QBE?AV12@II@Z
+ ?substring@String@WebCore@@QBE?AV12@II@Z
+ ?substring@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@II@Z
?symbolTableGet@JSVariableObject@JSC@@IAE_NABVIdentifier@2@AAVPropertyDescriptor@2@@Z
?synthesizePrototype@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z
+ ?textAtom@WebCore@@3VAtomicString@1@B
?thisObject@DebuggerCallFrame@JSC@@QBEPAVJSObject@2@XZ
+ ?threadsafeCopy@String@WebCore@@QBE?AV12@XZ
?throwError@JSC@@YAPAVJSObject@1@PAVExecState@1@W4ErrorType@1@@Z
?throwError@JSC@@YAPAVJSObject@1@PAVExecState@1@W4ErrorType@1@ABVUString@1@@Z
?throwError@JSC@@YAPAVJSObject@1@PAVExecState@1@W4ErrorType@1@PBD@Z
@@ -268,7 +373,14 @@ EXPORTS
?toBoolean@JSCell@JSC@@UBE_NPAVExecState@2@@Z
?toBoolean@JSObject@JSC@@UBE_NPAVExecState@2@@Z
?toBoolean@JSString@JSC@@EBE_NPAVExecState@2@@Z
+ ?toDouble@String@WebCore@@QBENPA_N@Z
+ ?toFloat@String@WebCore@@QBEMPA_N@Z
?toInt32SlowCase@JSC@@YAHNAA_N@Z
+ ?toInt@String@WebCore@@QBEHPA_N@Z
+ ?toInt@StringImpl@WebCore@@QAEHPA_N@Z
+ ?toIntPtr@String@WebCore@@QBEHPA_N@Z
+ ?toIntStrict@String@WebCore@@QBEHPA_NH@Z
+ ?toInteger@JSValue@JSC@@QBENPAVExecState@2@@Z
?toNumber@JSCell@JSC@@UBENPAVExecState@2@@Z
?toNumber@JSObject@JSC@@UBENPAVExecState@2@@Z
?toNumber@JSString@JSC@@EBENPAVExecState@2@@Z
@@ -282,17 +394,17 @@ EXPORTS
?toString@JSCell@JSC@@UBE?AVUString@2@PAVExecState@2@@Z
?toString@JSObject@JSC@@UBE?AVUString@2@PAVExecState@2@@Z
?toString@JSString@JSC@@EBE?AVUString@2@PAVExecState@2@@Z
- ?toThisJSString@JSCell@JSC@@UAEPAVJSString@2@PAVExecState@2@@Z
- ?toThisJSString@JSString@JSC@@EAEPAV12@PAVExecState@2@@Z
?toThisObject@JSCell@JSC@@UBEPAVJSObject@2@PAVExecState@2@@Z
?toThisObject@JSObject@JSC@@UBEPAV12@PAVExecState@2@@Z
?toThisObject@JSString@JSC@@EBEPAVJSObject@2@PAVExecState@2@@Z
?toThisObjectSlowCase@JSValue@JSC@@ABEPAVJSObject@2@PAVExecState@2@@Z
- ?toThisString@JSCell@JSC@@UBE?AVUString@2@PAVExecState@2@@Z
- ?toThisString@JSString@JSC@@EBE?AVUString@2@PAVExecState@2@@Z
?toUInt32@UString@JSC@@QBEIPA_N@Z
?toUInt32@UString@JSC@@QBEIPA_N_N@Z
?toUInt32SlowCase@JSC@@YAINAA_N@Z
+ ?toUInt64@String@WebCore@@QBE_KPA_N@Z
+ ?toUInt@String@WebCore@@QBEIPA_N@Z
+ ?toUIntStrict@String@WebCore@@QBEIPA_NH@Z
+ ?truncate@String@WebCore@@QAEXI@Z
?tryFastCalloc@WTF@@YA?AUTryMallocReturnValue@1@II@Z
?tryFastMalloc@WTF@@YA?AUTryMallocReturnValue@1@I@Z
?tryLock@Mutex@WTF@@QAE_NXZ
@@ -300,11 +412,16 @@ EXPORTS
?unlock@JSLock@JSC@@SAXW4JSLockBehavior@2@@Z
?unlock@Mutex@WTF@@QAEXXZ
?unlockAtomicallyInitializedStaticMutex@WTF@@YAXXZ
- ?unprotect@Heap@JSC@@QAEXVJSValue@2@@Z
+ ?unprotect@Heap@JSC@@QAE_NVJSValue@2@@Z
?unwrappedObject@JSObject@JSC@@UAEPAV12@XZ
+ ?upper@String@WebCore@@QBE?AV12@XZ
+ ?upper@StringImpl@WebCore@@QAE?AV?$PassRefPtr@VStringImpl@WebCore@@@WTF@@XZ
+ ?utf8@String@WebCore@@QBE?AVCString@WTF@@XZ
?wait@ThreadCondition@WTF@@QAEXAAVMutex@2@@Z
?waitForThreadCompletion@WTF@@YAHIPAPAX@Z
?writable@PropertyDescriptor@JSC@@QBE_NXZ
+ ?xmlAtom@WebCore@@3VAtomicString@1@B
+ ?xmlnsAtom@WebCore@@3VAtomicString@1@B
WTFLog
WTFLogVerbose
WTFReportArgumentAssertionFailure
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
index 60022dd..158621a 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
@@ -74,6 +74,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -136,6 +137,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -197,6 +199,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -260,6 +263,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -323,6 +327,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -384,6 +389,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -446,6 +452,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
<Configuration
@@ -507,6 +514,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\text\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
</Configuration>
</Configurations>
@@ -1133,6 +1141,14 @@
>
</File>
<File
+ RelativePath="..\..\runtime\RopeImpl.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\runtime\RopeImpl.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\ScopeChain.cpp"
>
</File>
@@ -1205,6 +1221,10 @@
>
</File>
<File
+ RelativePath="..\..\runtime\Terminator.h"
+ >
+ </File>
+ <File
RelativePath="..\..\runtime\TimeoutChecker.cpp"
>
</File>
@@ -1221,10 +1241,6 @@
>
</File>
<File
- RelativePath="..\..\runtime\UStringImpl.cpp"
- >
- </File>
- <File
RelativePath="..\..\runtime\UStringImpl.h"
>
</File>
@@ -1397,6 +1413,18 @@
>
</File>
<File
+ RelativePath="..\..\API\JSWeakObjectMapRefInternal.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\API\JSWeakObjectMapRefPrivate.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\API\JSWeakObjectMapRefPrivate.h"
+ >
+ </File>
+ <File
RelativePath="..\..\API\JSValueRef.cpp"
>
</File>
@@ -1578,66 +1606,6 @@
</File>
</Filter>
<Filter
- Name="wrec"
- >
- <File
- RelativePath="..\..\wrec\CharacterClass.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wrec\CharacterClass.h"
- >
- </File>
- <File
- RelativePath="..\..\wrec\CharacterClassConstructor.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wrec\CharacterClassConstructor.h"
- >
- </File>
- <File
- RelativePath="..\..\wrec\Escapes.h"
- >
- </File>
- <File
- RelativePath="..\..\wrec\Quantifier.h"
- >
- </File>
- <File
- RelativePath="..\..\wrec\WREC.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wrec\WREC.h"
- >
- </File>
- <File
- RelativePath="..\..\wrec\WRECFunctors.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wrec\WRECFunctors.h"
- >
- </File>
- <File
- RelativePath="..\..\wrec\WRECGenerator.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wrec\WRECGenerator.h"
- >
- </File>
- <File
- RelativePath="..\..\wrec\WRECParser.cpp"
- >
- </File>
- <File
- RelativePath="..\..\wrec\WRECParser.h"
- >
- </File>
- </Filter>
- <Filter
Name="yarr"
>
<File
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops
index f489e79..4470819 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreCommon.vsprops
@@ -6,7 +6,7 @@
>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../pcre/;../../parser/;../../bytecompiler/;../../jit/;../../runtime/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;../../wrec/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\obj\JavaScriptCore\DerivedSources\&quot;;../../;../../API/;../../pcre/;../../parser/;../../bytecompiler/;../../jit/;../../runtime/;../../bytecode/;../../interpreter/;../../wtf/;../../profiler;../../assembler/;../../debugger/;&quot;$(WebKitLibrariesDir)\include&quot;;&quot;$(WebKitLibrariesDir)\include\private&quot;;&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\JavaScriptCore&quot;;&quot;$(WebKitOutputDir)\include\private&quot;;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;"
PreprocessorDefinitions="__STD_C"
/>
<Tool
@@ -17,7 +17,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wrec\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
+ CommandLine="mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\wtf\unicode\icu\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\parser\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\runtime\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\VM\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\bytecode\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\interpreter\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\assembler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\jit\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\debugger\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\profiler\*.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\create_hash_table&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)\..\..\pcre\pcre.h&quot; &quot;$(WebKitOutputDir)\include\private\JavaScriptCore&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(OutDir)\JavaScriptCore.resources&quot;&#x0D;&#x0A;xcopy /y /d &quot;$(ProjectDir)..\$(ProjectName).resources\*&quot; &quot;$(OutDir)\$(ProjectName).resources&quot;&#x0D;&#x0A;&#x0D;&#x0A;if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;"
/>
<Tool
Name="VCPreBuildEventTool"
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
index 92479bb..098ff08 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
+++ b/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCoreGenerated.make
@@ -9,12 +9,16 @@ all:
xcopy /y /d "..\..\API\JSContextRef.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\JSContextRefPrivate.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\JSObjectRef.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
+ xcopy /y /d "..\..\API\JSObjectRefPrivate.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\JSStringRef.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\JSStringRefCF.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\JSStringRefBSTR.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\JSValueRef.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\JavaScriptCore.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\JSRetainPtr.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
+ xcopy /y /d "..\..\API\JSWeakObjectMapRefInternal.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
+ xcopy /y /d "..\..\API\JSWeakObjectMapRefPrivate.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
+ xcopy /y /d "..\..\API\JSRetainPtr.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\OpaqueJSString.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
xcopy /y /d "..\..\API\WebKitAvailability.h" "$(WEBKITOUTPUTDIR)\include\JavaScriptCore"
-del "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore\stdbool.h" "$(WEBKITOUTPUTDIR)\include\private\JavaScriptCore\stdint.h"
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
index c5b826c..0145311 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
+++ b/JavaScriptCore/JavaScriptCore.vcproj/WTF/WTF.vcproj
@@ -537,6 +537,46 @@
>
</File>
<File
+ RelativePath="..\..\wtf\text\AtomicString.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\AtomicString.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\AtomicStringImpl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\CString.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\CString.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringHash.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringImpl.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\StringImpl.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\WTFString.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\text\WTFString.h"
+ >
+ </File>
+ <File
RelativePath="..\..\wtf\unicode\UTF8.cpp"
>
</File>
@@ -556,6 +596,14 @@
RelativePath="..\..\wtf\VectorTraits.h"
>
</File>
+ <File
+ RelativePath="..\..\wtf\WTFThreadData.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\wtf\WTFThreadData.h"
+ >
+ </File>
</Files>
<Globals>
</Globals>
diff --git a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops
index 61594e1..45fe975 100644
--- a/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops
+++ b/JavaScriptCore/JavaScriptCore.vcproj/jsc/jscCommon.vsprops
@@ -6,7 +6,7 @@
>
<Tool
Name="VCCLCompilerTool"
- AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\private&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../wrec/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;../../jit/;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
+ AdditionalIncludeDirectories="&quot;$(WebKitOutputDir)\include&quot;;&quot;$(WebKitOutputDir)\include\private&quot;;&quot;$(WebKitOutputDir)\obj\JavaScriptCore\$(ConfigurationName)\DerivedSources\&quot;;../../;&quot;../../os-win32/&quot;;../../pcre/;../../assembler/;../../API/;../../parser/;../../runtime/;../../VM/;../../bytecode/;../../interpreter/;../../wtf/;../../debugger/;../../bytecompiler/;../../profiler;../../jit/;&quot;$(WebKitLibrariesDir)\include\pthreads&quot;;&quot;$(WebKitLibrariesDir)\include&quot;"
PreprocessorDefinitions="__STD_C"
/>
<Tool
@@ -16,7 +16,7 @@
/>
<Tool
Name="VCPostBuildEventTool"
- CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\ASL$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\ASL$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;cmd /c&#x0D;&#x0A;"
+ CommandLine="if exist &quot;$(WebKitOutputDir)\buildfailed&quot; del &quot;$(WebKitOutputDir)\buildfailed&quot;&#x0D;&#x0A;&#x0D;&#x0A;mkdir 2&gt;NUL &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc40$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42.dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icudt42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuin42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\icuuc42$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\CoreFoundation$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; xcopy /y /d /e /i &quot;$(WebKitLibrariesDir)\bin\CoreFoundation.resources&quot; &quot;$(WebKitOutputDir)\bin\CoreFoundation.resources&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\pthreadVC2$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\objc$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\ASL$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\ASL$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;if exist &quot;$(WebKitLibrariesDir)\bin\libdispatch$(LibraryConfigSuffix).dll&quot; xcopy /y /d &quot;$(WebKitLibrariesDir)\bin\libdispatch$(LibraryConfigSuffix).dll&quot; &quot;$(WebKitOutputDir)\bin&quot;&#x0D;&#x0A;&#x0D;&#x0A;cmd /c&#x0D;&#x0A;"
/>
<Tool
Name="VCPreBuildEventTool"
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index 2410466..9dff7ef 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -78,15 +78,6 @@
1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D8DC0ED2205B00B89619 /* CallFrame.h */; settings = {ATTRIBUTES = (Private, ); }; };
1429D92F0ED22D7000B89619 /* JIT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D92D0ED22D7000B89619 /* JIT.cpp */; };
1429D9300ED22D7000B89619 /* JIT.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D92E0ED22D7000B89619 /* JIT.h */; };
- 1429D9C40ED23C3900B89619 /* CharacterClass.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429D9C20ED23C3900B89619 /* CharacterClass.cpp */; };
- 1429D9C50ED23C3900B89619 /* CharacterClass.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429D9C30ED23C3900B89619 /* CharacterClass.h */; };
- 1429DA4A0ED245EC00B89619 /* Quantifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429DA490ED245EC00B89619 /* Quantifier.h */; };
- 1429DA820ED2482900B89619 /* WRECFunctors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429DA800ED2482900B89619 /* WRECFunctors.cpp */; };
- 1429DA830ED2482900B89619 /* WRECFunctors.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429DA810ED2482900B89619 /* WRECFunctors.h */; };
- 1429DABF0ED263E700B89619 /* WRECParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429DABD0ED263E700B89619 /* WRECParser.h */; };
- 1429DAC00ED263E700B89619 /* WRECParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429DABE0ED263E700B89619 /* WRECParser.cpp */; };
- 1429DAE00ED2645B00B89619 /* WRECGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1429DADE0ED2645B00B89619 /* WRECGenerator.h */; };
- 1429DAE10ED2645B00B89619 /* WRECGenerator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1429DADF0ED2645B00B89619 /* WRECGenerator.cpp */; };
142D3939103E4560007DCB52 /* NumericStrings.h in Headers */ = {isa = PBXBuildFile; fileRef = 142D3938103E4560007DCB52 /* NumericStrings.h */; settings = {ATTRIBUTES = (Private, ); }; };
143A97E60A4A06E200456B66 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
1440057F0A5335640005F061 /* JSNode.c in Sources */ = {isa = PBXBuildFile; fileRef = 1440F6420A4F8B6A0005F061 /* JSNode.c */; };
@@ -195,8 +186,6 @@
655EB29B10CE2581001A990E /* NodesCodegen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 655EB29A10CE2581001A990E /* NodesCodegen.cpp */; };
65DFC93308EA173A00F7300B /* HashTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65DFC92D08EA173A00F7300B /* HashTable.cpp */; };
65FDE49C0BDD1D4A00E80111 /* Assertions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65E217B808E7EECC0023E5F6 /* Assertions.cpp */; settings = {COMPILER_FLAGS = "-Wno-missing-format-attribute"; }; };
- 7E2ADD8E0E79AAD500D50C51 /* CharacterClassConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E2ADD8D0E79AAD500D50C51 /* CharacterClassConstructor.h */; };
- 7E2ADD900E79AC1100D50C51 /* CharacterClassConstructor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E2ADD8F0E79AC1100D50C51 /* CharacterClassConstructor.cpp */; };
7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E4EE7080EBB7963005934AA /* StructureChain.h */; settings = {ATTRIBUTES = (Private, ); }; };
7E4EE70F0EBB7A5B005934AA /* StructureChain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */; };
7EFF00640EC05A9A00AA7C93 /* NodeInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7EFF00630EC05A9A00AA7C93 /* NodeInfo.h */; };
@@ -206,16 +195,28 @@
860161E50F3A83C100F84710 /* MacroAssemblerX86_64.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */; };
860161E60F3A83C100F84710 /* MacroAssemblerX86Common.h in Headers */ = {isa = PBXBuildFile; fileRef = 860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */; };
863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86565742115BE3DA00291F40 /* CString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86565740115BE3DA00291F40 /* CString.cpp */; };
+ 86565743115BE3DA00291F40 /* CString.h in Headers */ = {isa = PBXBuildFile; fileRef = 86565741115BE3DA00291F40 /* CString.h */; settings = {ATTRIBUTES = (Private, ); }; };
865F408810E7D56300947361 /* APIShims.h in Headers */ = {isa = PBXBuildFile; fileRef = 865F408710E7D56300947361 /* APIShims.h */; };
- 869083150E6518D7000D36ED /* WREC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 869083130E6518D7000D36ED /* WREC.cpp */; };
- 869083160E6518D7000D36ED /* WREC.h in Headers */ = {isa = PBXBuildFile; fileRef = 869083140E6518D7000D36ED /* WREC.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 868BFA08117CEFD100B908B1 /* AtomicString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA00117CEFD100B908B1 /* AtomicString.cpp */; };
+ 868BFA09117CEFD100B908B1 /* AtomicString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA01117CEFD100B908B1 /* AtomicString.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 868BFA0A117CEFD100B908B1 /* AtomicStringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 868BFA0D117CEFD100B908B1 /* StringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA05117CEFD100B908B1 /* StringHash.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 868BFA0E117CEFD100B908B1 /* StringImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA06117CEFD100B908B1 /* StringImpl.cpp */; };
+ 868BFA0F117CEFD100B908B1 /* StringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA07117CEFD100B908B1 /* StringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 868BFA15117CF19900B908B1 /* WTFString.cpp */; };
+ 868BFA18117CF19900B908B1 /* WTFString.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA16117CF19900B908B1 /* WTFString.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */ = {isa = PBXBuildFile; fileRef = 868BFA5F117D048200B908B1 /* StaticConstructors.h */; settings = {ATTRIBUTES = (Private, ); }; };
8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698B86810D44D9400D8D01B /* StringBuilder.h */; settings = {ATTRIBUTES = (Private, ); }; };
8698BB3910D86BAF00D8D01B /* UStringImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698BB3710D86BAF00D8D01B /* UStringImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 8698BB3A10D86BAF00D8D01B /* UStringImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8698BB3810D86BAF00D8D01B /* UStringImpl.cpp */; };
869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; };
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; };
86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */; };
+ 86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */; };
+ 86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AB7117E391E00DF5A90 /* RopeImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE1117E578100DF5A90 /* StringBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 86B99AE2117E578100DF5A90 /* StringImplBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; };
86CA032E1038E8440028A609 /* Executable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CA032D1038E8440028A609 /* Executable.cpp */; };
86CAFEE31035DDE60028A609 /* Executable.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CAFEE21035DDE60028A609 /* Executable.h */; settings = {ATTRIBUTES = (); }; };
@@ -223,6 +224,8 @@
86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85A20EE79B7400288682 /* JITCall.cpp */; };
86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */; };
86CCEFDE0F413F8900FD7F9E /* JITCode.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CCEFDD0F413F8900FD7F9E /* JITCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 86D08D5311793613006E5ED0 /* WTFThreadData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86D08D5111793613006E5ED0 /* WTFThreadData.cpp */; };
+ 86D08D5411793613006E5ED0 /* WTFThreadData.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D08D5211793613006E5ED0 /* WTFThreadData.h */; settings = {ATTRIBUTES = (Private, ); }; };
86D3B2C310156BDE002865E7 /* ARMAssembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86D3B2BF10156BDE002865E7 /* ARMAssembler.cpp */; };
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B2C010156BDE002865E7 /* ARMAssembler.h */; };
86D3B2C510156BDE002865E7 /* AssemblerBufferWithConstantPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */; };
@@ -279,11 +282,15 @@
969A07990ED1D3AE00F1F681 /* Instruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07930ED1D3AE00F1F681 /* Instruction.h */; };
969A079A0ED1D3AE00F1F681 /* Opcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 969A07940ED1D3AE00F1F681 /* Opcode.cpp */; };
969A079B0ED1D3AE00F1F681 /* Opcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 969A07950ED1D3AE00F1F681 /* Opcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 96A746410EDDF70600904779 /* Escapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 96A7463F0EDDF70600904779 /* Escapes.h */; };
96DD73790F9DA3100027FBCC /* VMTags.h in Headers */ = {isa = PBXBuildFile; fileRef = 96DD73780F9DA3100027FBCC /* VMTags.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 971EDEA61169E0D3005E4262 /* Terminator.h in Headers */ = {isa = PBXBuildFile; fileRef = 97F6903A1169DF7F00A6BB46 /* Terminator.h */; settings = {ATTRIBUTES = (Private, ); }; };
A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A72700780DAC605600E548D7 /* JSNotAnObject.cpp */; };
A72701B90DADE94900E548D7 /* ExceptionHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = A72701B30DADE94900E548D7 /* ExceptionHelpers.h */; };
A727FF6B0DA3092200E548D7 /* JSPropertyNameIterator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */; };
+ A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */; };
+ A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
A74B3499102A5F8E0032AB98 /* MarkStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74B3498102A5F8E0032AB98 /* MarkStack.cpp */; };
A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; };
A76EE6590FAE59D5003F069A /* NativeFunctionWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = A76EE6580FAE59D5003F069A /* NativeFunctionWrapper.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -565,7 +572,6 @@
088FA5B90EF76D4300578E6F /* RandomNumber.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RandomNumber.cpp; sourceTree = "<group>"; };
088FA5BA0EF76D4300578E6F /* RandomNumber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumber.h; sourceTree = "<group>"; };
08E279E80EF83B10007DB523 /* RandomNumberSeed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RandomNumberSeed.h; sourceTree = "<group>"; };
- 0B1F921B0F17502D0036468E /* PtrAndFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PtrAndFlags.h; sourceTree = "<group>"; };
0B330C260F38C62300692DE3 /* TypeTraits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TypeTraits.cpp; sourceTree = "<group>"; };
0B4D7E620F319AC800AD7E58 /* TypeTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypeTraits.h; sourceTree = "<group>"; };
0BDFFAD10FC616EC00D69EF4 /* OwnFastMallocPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OwnFastMallocPtr.h; sourceTree = "<group>"; };
@@ -589,15 +595,6 @@
1429D8DC0ED2205B00B89619 /* CallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallFrame.h; sourceTree = "<group>"; };
1429D92D0ED22D7000B89619 /* JIT.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JIT.cpp; sourceTree = "<group>"; };
1429D92E0ED22D7000B89619 /* JIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JIT.h; sourceTree = "<group>"; };
- 1429D9C20ED23C3900B89619 /* CharacterClass.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CharacterClass.cpp; sourceTree = "<group>"; };
- 1429D9C30ED23C3900B89619 /* CharacterClass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharacterClass.h; sourceTree = "<group>"; };
- 1429DA490ED245EC00B89619 /* Quantifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Quantifier.h; sourceTree = "<group>"; };
- 1429DA800ED2482900B89619 /* WRECFunctors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WRECFunctors.cpp; sourceTree = "<group>"; };
- 1429DA810ED2482900B89619 /* WRECFunctors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WRECFunctors.h; sourceTree = "<group>"; };
- 1429DABD0ED263E700B89619 /* WRECParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WRECParser.h; sourceTree = "<group>"; };
- 1429DABE0ED263E700B89619 /* WRECParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WRECParser.cpp; sourceTree = "<group>"; };
- 1429DADE0ED2645B00B89619 /* WRECGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WRECGenerator.h; sourceTree = "<group>"; };
- 1429DADF0ED2645B00B89619 /* WRECGenerator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WRECGenerator.cpp; sourceTree = "<group>"; };
142D3938103E4560007DCB52 /* NumericStrings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NumericStrings.h; sourceTree = "<group>"; };
1440051F0A531D3B0005F061 /* Node.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Node.h; path = tests/Node.h; sourceTree = "<group>"; };
144005200A531D3B0005F061 /* Node.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Node.c; path = tests/Node.c; sourceTree = "<group>"; };
@@ -731,8 +728,6 @@
65EA73630BAE35D1001BB560 /* CommonIdentifiers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CommonIdentifiers.h; sourceTree = "<group>"; };
65FB3F4809D11B2400F49DEB /* Grammar.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Grammar.cpp; sourceTree = "<group>"; };
704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; };
- 7E2ADD8D0E79AAD500D50C51 /* CharacterClassConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CharacterClassConstructor.h; sourceTree = "<group>"; };
- 7E2ADD8F0E79AC1100D50C51 /* CharacterClassConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CharacterClassConstructor.cpp; sourceTree = "<group>"; };
7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScopeChainMark.h; sourceTree = "<group>"; };
7E4EE7080EBB7963005934AA /* StructureChain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureChain.h; sourceTree = "<group>"; };
7E4EE70E0EBB7A5B005934AA /* StructureChain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StructureChain.cpp; sourceTree = "<group>"; };
@@ -742,16 +737,28 @@
860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86_64.h; sourceTree = "<group>"; };
860161E20F3A83C100F84710 /* MacroAssemblerX86Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerX86Common.h; sourceTree = "<group>"; };
863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; };
+ 86565740115BE3DA00291F40 /* CString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CString.cpp; path = text/CString.cpp; sourceTree = "<group>"; };
+ 86565741115BE3DA00291F40 /* CString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CString.h; path = text/CString.h; sourceTree = "<group>"; };
865F408710E7D56300947361 /* APIShims.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIShims.h; sourceTree = "<group>"; };
- 869083130E6518D7000D36ED /* WREC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WREC.cpp; sourceTree = "<group>"; };
- 869083140E6518D7000D36ED /* WREC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WREC.h; sourceTree = "<group>"; };
+ 868BFA00117CEFD100B908B1 /* AtomicString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AtomicString.cpp; path = text/AtomicString.cpp; sourceTree = "<group>"; };
+ 868BFA01117CEFD100B908B1 /* AtomicString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicString.h; path = text/AtomicString.h; sourceTree = "<group>"; };
+ 868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AtomicStringImpl.h; path = text/AtomicStringImpl.h; sourceTree = "<group>"; };
+ 868BFA05117CEFD100B908B1 /* StringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringHash.h; path = text/StringHash.h; sourceTree = "<group>"; };
+ 868BFA06117CEFD100B908B1 /* StringImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringImpl.cpp; path = text/StringImpl.cpp; sourceTree = "<group>"; };
+ 868BFA07117CEFD100B908B1 /* StringImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringImpl.h; path = text/StringImpl.h; sourceTree = "<group>"; };
+ 868BFA15117CF19900B908B1 /* WTFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WTFString.cpp; path = text/WTFString.cpp; sourceTree = "<group>"; };
+ 868BFA16117CF19900B908B1 /* WTFString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WTFString.h; path = text/WTFString.h; sourceTree = "<group>"; };
+ 868BFA5F117D048200B908B1 /* StaticConstructors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticConstructors.h; sourceTree = "<group>"; };
8698B86810D44D9400D8D01B /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; };
8698BB3710D86BAF00D8D01B /* UStringImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UStringImpl.h; sourceTree = "<group>"; };
- 8698BB3810D86BAF00D8D01B /* UStringImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UStringImpl.cpp; sourceTree = "<group>"; };
869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; };
86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; };
86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARMv7.h; sourceTree = "<group>"; };
+ 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RopeImpl.cpp; sourceTree = "<group>"; };
+ 86B99AB7117E391E00DF5A90 /* RopeImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RopeImpl.h; sourceTree = "<group>"; };
+ 86B99AE1117E578100DF5A90 /* StringBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringBuffer.h; path = text/StringBuffer.h; sourceTree = "<group>"; };
+ 86B99AE2117E578100DF5A90 /* StringImplBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringImplBase.h; path = text/StringImplBase.h; sourceTree = "<group>"; };
86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssembler.h; sourceTree = "<group>"; };
86CA032D1038E8440028A609 /* Executable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Executable.cpp; sourceTree = "<group>"; };
86CAFEE21035DDE60028A609 /* Executable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Executable.h; sourceTree = "<group>"; };
@@ -759,6 +766,8 @@
86CC85A20EE79B7400288682 /* JITCall.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITCall.cpp; sourceTree = "<group>"; };
86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITPropertyAccess.cpp; sourceTree = "<group>"; };
86CCEFDD0F413F8900FD7F9E /* JITCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITCode.h; sourceTree = "<group>"; };
+ 86D08D5111793613006E5ED0 /* WTFThreadData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WTFThreadData.cpp; sourceTree = "<group>"; };
+ 86D08D5211793613006E5ED0 /* WTFThreadData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFThreadData.h; sourceTree = "<group>"; };
86D3B2BF10156BDE002865E7 /* ARMAssembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMAssembler.cpp; sourceTree = "<group>"; };
86D3B2C010156BDE002865E7 /* ARMAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMAssembler.h; sourceTree = "<group>"; };
86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerBufferWithConstantPool.h; sourceTree = "<group>"; };
@@ -844,19 +853,25 @@
969A07940ED1D3AE00F1F681 /* Opcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Opcode.cpp; sourceTree = "<group>"; };
969A07950ED1D3AE00F1F681 /* Opcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Opcode.h; sourceTree = "<group>"; };
969A09220ED1E09C00F1F681 /* Completion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Completion.cpp; sourceTree = "<group>"; };
- 96A7463F0EDDF70600904779 /* Escapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Escapes.h; sourceTree = "<group>"; };
96DD73780F9DA3100027FBCC /* VMTags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMTags.h; sourceTree = "<group>"; };
+ 97F6903A1169DF7F00A6BB46 /* Terminator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Terminator.h; sourceTree = "<group>"; };
+ A718F61A11754A21002465A7 /* RegExpJitTables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpJitTables.h; sourceTree = "<group>"; };
+ A718F8211178EB4B002465A7 /* create_regex_tables */ = {isa = PBXFileReference; explicitFileType = text.script.python; fileEncoding = 4; path = create_regex_tables; sourceTree = "<group>"; };
A72700770DAC605600E548D7 /* JSNotAnObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNotAnObject.h; sourceTree = "<group>"; };
A72700780DAC605600E548D7 /* JSNotAnObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNotAnObject.cpp; sourceTree = "<group>"; };
A72701B30DADE94900E548D7 /* ExceptionHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExceptionHelpers.h; sourceTree = "<group>"; };
A727FF650DA3053B00E548D7 /* JSPropertyNameIterator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPropertyNameIterator.h; sourceTree = "<group>"; };
A727FF660DA3053B00E548D7 /* JSPropertyNameIterator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPropertyNameIterator.cpp; sourceTree = "<group>"; };
+ A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefPrivate.h; sourceTree = "<group>"; };
+ A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakObjectMapRefPrivate.cpp; sourceTree = "<group>"; };
+ A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefInternal.h; sourceTree = "<group>"; };
A74B3498102A5F8E0032AB98 /* MarkStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkStack.cpp; sourceTree = "<group>"; };
A76EE6580FAE59D5003F069A /* NativeFunctionWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NativeFunctionWrapper.h; sourceTree = "<group>"; };
A779558F101A74D500114E55 /* MarkStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkStack.h; sourceTree = "<group>"; };
A782F1A40EEC9FA20036273F /* ExecutableAllocatorPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ExecutableAllocatorPosix.cpp; sourceTree = "<group>"; };
A791EF260F11E07900AE1F68 /* JSByteArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSByteArray.h; sourceTree = "<group>"; };
A791EF270F11E07900AE1F68 /* JSByteArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSByteArray.cpp; sourceTree = "<group>"; };
+ A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObjectRefPrivate.h; sourceTree = "<group>"; };
A7A1F7AA0F252B3C00E184E2 /* ByteArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ByteArray.cpp; sourceTree = "<group>"; };
A7A1F7AB0F252B3C00E184E2 /* ByteArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByteArray.h; sourceTree = "<group>"; };
A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExecutableAllocator.h; sourceTree = "<group>"; };
@@ -1102,6 +1117,7 @@
0867D691FE84028FC02AAC07 /* JavaScriptCore */ = {
isa = PBXGroup;
children = (
+ A718F8211178EB4B002465A7 /* create_regex_tables */,
937B63CC09E766D200A671DD /* DerivedSources.make */,
F692A8540255597D01FF60F7 /* create_hash_table */,
14B8ECA60A5653980062BE54 /* JavaScriptCore.exp */,
@@ -1120,7 +1136,6 @@
95AB831A0DA42C6900BC83F3 /* profiler */,
7EF6E0BB0EB7A1EC0079AFAF /* runtime */,
141211000A48772600480255 /* tests */,
- 869083120E6518D7000D36ED /* wrec */,
65162EF108E6A21C007556CD /* wtf */,
86EAC48C0F93E8B9008EC948 /* yarr */,
1C90513E0BA9E8830081E9D0 /* Configurations */,
@@ -1190,10 +1205,10 @@
86CC85A00EE79A4700288682 /* JITInlineMethods.h */,
BCDD51E90FB8DF74004A8BDC /* JITOpcodes.cpp */,
86CC85C30EE7A89400288682 /* JITPropertyAccess.cpp */,
+ A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */,
960626950FB8EC02009798AB /* JITStubCall.h */,
14A23D6C0F4E19CE0023CDAD /* JITStubs.cpp */,
14A6581A0F4E36F4000150FD /* JITStubs.h */,
- A7C1E8C8112E701C00A37F98 /* JITPropertyAccess32_64.cpp */,
);
path = jit;
sourceTree = "<group>";
@@ -1224,6 +1239,7 @@
148CD1D7108CF902008163C6 /* JSContextRefPrivate.h */,
1482B7E20A43076000517CFC /* JSObjectRef.cpp */,
1482B7E10A43076000517CFC /* JSObjectRef.h */,
+ A79EDB0811531CD60019E912 /* JSObjectRefPrivate.h */,
95988BA90E477BEC00D28D4D /* JSProfilerPrivate.cpp */,
952C63AC0E4777D600C13936 /* JSProfilerPrivate.h */,
95C18D3E0C90E7EF00E72F73 /* JSRetainPtr.h */,
@@ -1236,6 +1252,9 @@
E124A8F60E555775003091F1 /* OpaqueJSString.cpp */,
E124A8F50E555775003091F1 /* OpaqueJSString.h */,
5DE3D0F40DD8DDFB00468714 /* WebKitAvailability.h */,
+ A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */,
+ A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */,
+ A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */,
);
path = API;
sourceTree = "<group>";
@@ -1290,6 +1309,7 @@
650FDF8D09D0FCA700769E54 /* Derived Sources */ = {
isa = PBXGroup;
children = (
+ A718F61A11754A21002465A7 /* RegExpJitTables.h */,
BC18C5230E16FC8A00B34460 /* ArrayPrototype.lut.h */,
65B174BE09D1000200820339 /* chartables.c */,
BCD203E70E1718F4002C7E82 /* DatePrototype.lut.h */,
@@ -1314,6 +1334,7 @@
isa = PBXGroup;
children = (
06D358A00DAAD9C4003B174E /* mac */,
+ 8656573E115BE35200291F40 /* text */,
E195678D09E7CF1200B89D13 /* unicode */,
93AA4F770957251F0084B3A7 /* AlwaysInline.h */,
938C4F690CA06BC700D9310A /* ASCIICType.h */,
@@ -1362,7 +1383,6 @@
6580F795094070560082C219 /* PassRefPtr.h */,
65D6D87E09B5A32E0002E4D7 /* Platform.h */,
A7D649A91015224E009B2E1B /* PossiblyNull.h */,
- 0B1F921B0F17502D0036468E /* PtrAndFlags.h */,
088FA5B90EF76D4300578E6F /* RandomNumber.cpp */,
088FA5BA0EF76D4300578E6F /* RandomNumber.h */,
08E279E80EF83B10007DB523 /* RandomNumberSeed.h */,
@@ -1373,6 +1393,7 @@
148A1ECD0D10C23B0069A47C /* RefPtrHashMap.h */,
51F648D60BB4E2CA0033D760 /* RetainPtr.h */,
969A07290ED1CE6900F1F681 /* SegmentedVector.h */,
+ 868BFA5F117D048200B908B1 /* StaticConstructors.h */,
FE1B44790ECCD73B004F4DD1 /* StdLibExtras.h */,
E11D51750B2E798D0056C188 /* StringExtras.h */,
5D63E9AC10F2BD6E00FC8AE9 /* StringHashFunctions.h */,
@@ -1394,6 +1415,8 @@
6592C316098B7DE10003D4F6 /* Vector.h */,
6592C317098B7DE10003D4F6 /* VectorTraits.h */,
96DD73780F9DA3100027FBCC /* VMTags.h */,
+ 86D08D5111793613006E5ED0 /* WTFThreadData.cpp */,
+ 86D08D5211793613006E5ED0 /* WTFThreadData.h */,
);
path = wtf;
sourceTree = "<group>";
@@ -1611,6 +1634,8 @@
F692A87C0255597D01FF60F7 /* RegExpObject.h */,
BCD202BF0E1706A7002C7E82 /* RegExpPrototype.cpp */,
BCD202C00E1706A7002C7E82 /* RegExpPrototype.h */,
+ 86B99AB6117E391E00DF5A90 /* RopeImpl.cpp */,
+ 86B99AB7117E391E00DF5A90 /* RopeImpl.h */,
9374D3A8038D9D74008635CE /* ScopeChain.cpp */,
9374D3A7038D9D74008635CE /* ScopeChain.h */,
7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */,
@@ -1630,13 +1655,13 @@
7E4EE7080EBB7963005934AA /* StructureChain.h */,
BC9041470EB9250900FE26FA /* StructureTransitionTable.h */,
14A396A60CD2933100B5B4FF /* SymbolTable.h */,
+ 97F6903A1169DF7F00A6BB46 /* Terminator.h */,
14A42E3D0F4F60EE00599099 /* TimeoutChecker.cpp */,
14A42E3E0F4F60EE00599099 /* TimeoutChecker.h */,
5D53726D0E1C546B0021E549 /* Tracing.d */,
5D53726E0E1C54880021E549 /* Tracing.h */,
F692A8850255597D01FF60F7 /* UString.cpp */,
F692A8860255597D01FF60F7 /* UString.h */,
- 8698BB3810D86BAF00D8D01B /* UStringImpl.cpp */,
8698BB3710D86BAF00D8D01B /* UStringImpl.h */,
14BFCE6810CDB1FC00364CCE /* WeakGCMap.h */,
14035DB010DBFB2A00FFFFE7 /* WeakGCPtr.h */,
@@ -1645,25 +1670,23 @@
path = runtime;
sourceTree = "<group>";
};
- 869083120E6518D7000D36ED /* wrec */ = {
+ 8656573E115BE35200291F40 /* text */ = {
isa = PBXGroup;
children = (
- 1429D9C20ED23C3900B89619 /* CharacterClass.cpp */,
- 1429D9C30ED23C3900B89619 /* CharacterClass.h */,
- 7E2ADD8F0E79AC1100D50C51 /* CharacterClassConstructor.cpp */,
- 7E2ADD8D0E79AAD500D50C51 /* CharacterClassConstructor.h */,
- 96A7463F0EDDF70600904779 /* Escapes.h */,
- 1429DA490ED245EC00B89619 /* Quantifier.h */,
- 869083130E6518D7000D36ED /* WREC.cpp */,
- 869083140E6518D7000D36ED /* WREC.h */,
- 1429DA800ED2482900B89619 /* WRECFunctors.cpp */,
- 1429DA810ED2482900B89619 /* WRECFunctors.h */,
- 1429DADF0ED2645B00B89619 /* WRECGenerator.cpp */,
- 1429DADE0ED2645B00B89619 /* WRECGenerator.h */,
- 1429DABE0ED263E700B89619 /* WRECParser.cpp */,
- 1429DABD0ED263E700B89619 /* WRECParser.h */,
- );
- path = wrec;
+ 868BFA00117CEFD100B908B1 /* AtomicString.cpp */,
+ 868BFA01117CEFD100B908B1 /* AtomicString.h */,
+ 868BFA02117CEFD100B908B1 /* AtomicStringImpl.h */,
+ 86565740115BE3DA00291F40 /* CString.cpp */,
+ 86565741115BE3DA00291F40 /* CString.h */,
+ 86B99AE1117E578100DF5A90 /* StringBuffer.h */,
+ 868BFA05117CEFD100B908B1 /* StringHash.h */,
+ 868BFA06117CEFD100B908B1 /* StringImpl.cpp */,
+ 868BFA07117CEFD100B908B1 /* StringImpl.h */,
+ 86B99AE2117E578100DF5A90 /* StringImplBase.h */,
+ 868BFA15117CF19900B908B1 /* WTFString.cpp */,
+ 868BFA16117CF19900B908B1 /* WTFString.h */,
+ );
+ name = text;
sourceTree = "<group>";
};
86EAC48C0F93E8B9008EC948 /* yarr */ = {
@@ -1817,8 +1840,6 @@
BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
1429D8DE0ED2205B00B89619 /* CallFrame.h in Headers */,
95E3BC050E1AE68200B2D1C1 /* CallIdentifier.h in Headers */,
- 1429D9C50ED23C3900B89619 /* CharacterClass.h in Headers */,
- 7E2ADD8E0E79AAD500D50C51 /* CharacterClassConstructor.h in Headers */,
BC6AAAE50E1F426500AD87D8 /* ClassInfo.h in Headers */,
969A07970ED1D3AE00F1F681 /* CodeBlock.h in Headers */,
86E116B10FE75AC800B512BC /* CodeLocation.h in Headers */,
@@ -1849,7 +1870,6 @@
BC02E90D0E1839DB000F9297 /* ErrorConstructor.h in Headers */,
BC02E98D0E183E38000F9297 /* ErrorInstance.h in Headers */,
BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */,
- 96A746410EDDF70600904779 /* Escapes.h in Headers */,
969A07980ED1D3AE00F1F681 /* EvalCodeCache.h in Headers */,
BC18C4000E16F5CD00B34460 /* ExceptionHelpers.h in Headers */,
86CAFEE31035DDE60028A609 /* Executable.h in Headers */,
@@ -1910,6 +1930,7 @@
9534AAFB0E5B7A9600B8A45B /* JSProfilerPrivate.h in Headers */,
BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */,
BC18C4270E16F5CD00B34460 /* JSString.h in Headers */,
+ 86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */,
BC18C4280E16F5CD00B34460 /* JSStringRef.h in Headers */,
BC18C4290E16F5CD00B34460 /* JSStringRefCF.h in Headers */,
BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */,
@@ -1984,7 +2005,6 @@
BC18C4560E16F5CD00B34460 /* Protect.h in Headers */,
BC257DF40E1F53740016B6C9 /* PrototypeFunction.h in Headers */,
147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */,
- 1429DA4A0ED245EC00B89619 /* Quantifier.h in Headers */,
088FA5BC0EF76D4300578E6F /* RandomNumber.h in Headers */,
08E279E90EF83B10007DB523 /* RandomNumberSeed.h in Headers */,
BC18C4570E16F5CD00B34460 /* RefCounted.h in Headers */,
@@ -2035,6 +2055,7 @@
18BAB55410DAE066000D945B /* ThreadIdentifierDataPthreads.h in Headers */,
BC18C4700E16F5CD00B34460 /* Threading.h in Headers */,
BC18C4710E16F5CD00B34460 /* ThreadSpecific.h in Headers */,
+ 971EDEA61169E0D3005E4262 /* Terminator.h in Headers */,
14A42E400F4F60EE00599099 /* TimeoutChecker.h in Headers */,
5D53726F0E1C54880021E549 /* Tracing.h in Headers */,
0B4D7E630F319AC800AD7E58 /* TypeTraits.h in Headers */,
@@ -2045,6 +2066,7 @@
BC18C4760E16F5CD00B34460 /* UString.h in Headers */,
8698BB3910D86BAF00D8D01B /* UStringImpl.h in Headers */,
BC18C4770E16F5CD00B34460 /* UTF8.h in Headers */,
+ E17FF771112131D200076A19 /* ValueCheck.h in Headers */,
BC18C4780E16F5CD00B34460 /* Vector.h in Headers */,
BC18C4790E16F5CD00B34460 /* VectorTraits.h in Headers */,
96DD73790F9DA3100027FBCC /* VMTags.h in Headers */,
@@ -2052,13 +2074,21 @@
14035DB110DBFB2A00FFFFE7 /* WeakGCPtr.h in Headers */,
1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */,
BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */,
- 869083160E6518D7000D36ED /* WREC.h in Headers */,
- 1429DA830ED2482900B89619 /* WRECFunctors.h in Headers */,
- 1429DAE00ED2645B00B89619 /* WRECGenerator.h in Headers */,
- 1429DABF0ED263E700B89619 /* WRECParser.h in Headers */,
9688CB160ED12B4E001D649F /* X86Assembler.h in Headers */,
- 86E85539111B9968001AF51E /* JSStringBuilder.h in Headers */,
- E17FF771112131D200076A19 /* ValueCheck.h in Headers */,
+ A7280A2811557E3000D56957 /* JSObjectRefPrivate.h in Headers */,
+ 86565743115BE3DA00291F40 /* CString.h in Headers */,
+ A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
+ A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
+ 86D08D5411793613006E5ED0 /* WTFThreadData.h in Headers */,
+ 868BFA09117CEFD100B908B1 /* AtomicString.h in Headers */,
+ 868BFA0A117CEFD100B908B1 /* AtomicStringImpl.h in Headers */,
+ 868BFA0D117CEFD100B908B1 /* StringHash.h in Headers */,
+ 868BFA0F117CEFD100B908B1 /* StringImpl.h in Headers */,
+ 868BFA18117CF19900B908B1 /* WTFString.h in Headers */,
+ 868BFA60117D048200B908B1 /* StaticConstructors.h in Headers */,
+ 86B99AB9117E391E00DF5A90 /* RopeImpl.h in Headers */,
+ 86B99AE3117E578100DF5A90 /* StringBuffer.h in Headers */,
+ 86B99AE4117E578100DF5A90 /* StringImplBase.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2358,8 +2388,6 @@
148F21AA107EC53A0042EC2C /* BytecodeGenerator.cpp in Sources */,
1428082D107EC0570013E7B2 /* CallData.cpp in Sources */,
1429D8DD0ED2205B00B89619 /* CallFrame.cpp in Sources */,
- 1429D9C40ED23C3900B89619 /* CharacterClass.cpp in Sources */,
- 7E2ADD900E79AC1100D50C51 /* CharacterClassConstructor.cpp in Sources */,
969A07960ED1D3AE00F1F681 /* CodeBlock.cpp in Sources */,
E1A862D60D7F2B5C001EC6AA /* CollatorDefault.cpp in Sources */,
E1A862A90D7EBB76001EC6AA /* CollatorICU.cpp in Sources */,
@@ -2402,6 +2430,7 @@
86CC85A30EE79B7400288682 /* JITCall.cpp in Sources */,
BCDD51EB0FB8DF74004A8BDC /* JITOpcodes.cpp in Sources */,
86CC85C40EE7A89400288682 /* JITPropertyAccess.cpp in Sources */,
+ A7C1E8E4112E72EF00A37F98 /* JITPropertyAccess32_64.cpp in Sources */,
14A23D750F4E1ABB0023CDAD /* JITStubs.cpp in Sources */,
140B7D1D0DC69AF7009C42B8 /* JSActivation.cpp in Sources */,
140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */,
@@ -2499,13 +2528,14 @@
14A42E3F0F4F60EE00599099 /* TimeoutChecker.cpp in Sources */,
0B330C270F38C62300692DE3 /* TypeTraits.cpp in Sources */,
14469DEE107EC7E700650446 /* UString.cpp in Sources */,
- 8698BB3A10D86BAF00D8D01B /* UStringImpl.cpp in Sources */,
E1EF79AA0CE97BA60088D500 /* UTF8.cpp in Sources */,
- 869083150E6518D7000D36ED /* WREC.cpp in Sources */,
- 1429DA820ED2482900B89619 /* WRECFunctors.cpp in Sources */,
- 1429DAE10ED2645B00B89619 /* WRECGenerator.cpp in Sources */,
- 1429DAC00ED263E700B89619 /* WRECParser.cpp in Sources */,
- A7C1E8E4112E72EF00A37F98 /* JITPropertyAccess32_64.cpp in Sources */,
+ 86565742115BE3DA00291F40 /* CString.cpp in Sources */,
+ A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */,
+ 86D08D5311793613006E5ED0 /* WTFThreadData.cpp in Sources */,
+ 868BFA08117CEFD100B908B1 /* AtomicString.cpp in Sources */,
+ 868BFA0E117CEFD100B908B1 /* StringImpl.cpp in Sources */,
+ 868BFA17117CF19900B908B1 /* WTFString.cpp in Sources */,
+ 86B99AB8117E391E00DF5A90 /* RopeImpl.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/JavaScriptCore/assembler/ARMAssembler.cpp b/JavaScriptCore/assembler/ARMAssembler.cpp
index 6dd2b87..7393aa1 100644
--- a/JavaScriptCore/assembler/ARMAssembler.cpp
+++ b/JavaScriptCore/assembler/ARMAssembler.cpp
@@ -262,28 +262,29 @@ ARMWord ARMAssembler::encodeComplexImm(ARMWord imm, int dest)
// 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)
- 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));
- dtr_u(isLoad, srcDst, ARMRegisters::S0, offset & 0xfff);
+ dtr_u(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag);
} 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)
- 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));
- dtr_d(isLoad, srcDst, ARMRegisters::S0, offset & 0xfff);
+ dtr_d(isLoad, srcDst, ARMRegisters::S0, (offset & 0xfff) | transferFlag);
} else {
ARMWord reg = getImm(offset, ARMRegisters::S0);
- dtr_dr(isLoad, srcDst, base, reg);
+ dtr_dr(isLoad, srcDst, base, reg | transferFlag);
}
}
}
diff --git a/JavaScriptCore/assembler/ARMAssembler.h b/JavaScriptCore/assembler/ARMAssembler.h
index 6967b37..f93db68 100644
--- a/JavaScriptCore/assembler/ARMAssembler.h
+++ b/JavaScriptCore/assembler/ARMAssembler.h
@@ -27,8 +27,6 @@
#ifndef ARMAssembler_h
#define ARMAssembler_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#include "AssemblerBufferWithConstantPool.h"
@@ -155,6 +153,7 @@ namespace JSC {
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),
@@ -780,7 +779,7 @@ namespace JSC {
// 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);
diff --git a/JavaScriptCore/assembler/ARMv7Assembler.h b/JavaScriptCore/assembler/ARMv7Assembler.h
index 4e394b2..21279f5 100644
--- a/JavaScriptCore/assembler/ARMv7Assembler.h
+++ b/JavaScriptCore/assembler/ARMv7Assembler.h
@@ -1,5 +1,6 @@
/*
* 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
@@ -26,8 +27,6 @@
#ifndef ARMAssembler_h
#define ARMAssembler_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER) && CPU(ARM_THUMB2)
#include "AssemblerBuffer.h"
@@ -582,11 +581,13 @@ private:
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_LDRH_reg_T1 = 0x5A00,
+ OP_LDRB_reg_T1 = 0x5C00,
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,
@@ -631,12 +632,15 @@ private:
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_LDRB_imm_T2 = 0xF890,
OP_LDRH_imm_T2 = 0xF8B0,
OP_STR_imm_T3 = 0xF8C0,
OP_LDR_imm_T3 = 0xF8D0,
@@ -1080,6 +1084,52 @@ public:
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));
diff --git a/JavaScriptCore/assembler/AbstractMacroAssembler.h b/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 198e8d1..f96e34a 100644
--- a/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -26,8 +26,6 @@
#ifndef AbstractMacroAssembler_h
#define AbstractMacroAssembler_h
-#include <wtf/Platform.h>
-
#include <MacroAssemblerCodeRef.h>
#include <CodeLocation.h>
#include <wtf/Noncopyable.h>
@@ -83,6 +81,17 @@ public:
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
@@ -173,7 +182,7 @@ public:
struct Imm32 {
explicit Imm32(int32_t value)
: m_value(value)
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
, m_isPointer(false)
#endif
{
@@ -182,7 +191,7 @@ public:
#if !CPU(X86_64)
explicit Imm32(ImmPtr ptr)
: m_value(ptr.asIntptr())
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
, m_isPointer(true)
#endif
{
@@ -190,13 +199,14 @@ public:
#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.
+ // Same for MIPS.
bool m_isPointer;
#endif
};
diff --git a/JavaScriptCore/assembler/AssemblerBuffer.h b/JavaScriptCore/assembler/AssemblerBuffer.h
index 073906a..e2fb8a1 100644
--- a/JavaScriptCore/assembler/AssemblerBuffer.h
+++ b/JavaScriptCore/assembler/AssemblerBuffer.h
@@ -26,8 +26,6 @@
#ifndef AssemblerBuffer_h
#define AssemblerBuffer_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER)
#include "stdint.h"
diff --git a/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h b/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
index af3c3be..b1c537e 100644
--- a/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
+++ b/JavaScriptCore/assembler/AssemblerBufferWithConstantPool.h
@@ -27,8 +27,6 @@
#ifndef AssemblerBufferWithConstantPool_h
#define AssemblerBufferWithConstantPool_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER)
#include "AssemblerBuffer.h"
diff --git a/JavaScriptCore/assembler/CodeLocation.h b/JavaScriptCore/assembler/CodeLocation.h
index b910b6f..cab28cd 100644
--- a/JavaScriptCore/assembler/CodeLocation.h
+++ b/JavaScriptCore/assembler/CodeLocation.h
@@ -26,7 +26,6 @@
#ifndef CodeLocation_h
#define CodeLocation_h
-#include <wtf/Platform.h>
#include <MacroAssemblerCodeRef.h>
diff --git a/JavaScriptCore/assembler/LinkBuffer.h b/JavaScriptCore/assembler/LinkBuffer.h
index 6d08117..47cac5a 100644
--- a/JavaScriptCore/assembler/LinkBuffer.h
+++ b/JavaScriptCore/assembler/LinkBuffer.h
@@ -26,8 +26,6 @@
#ifndef LinkBuffer_h
#define LinkBuffer_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER)
#include <MacroAssembler.h>
diff --git a/JavaScriptCore/assembler/MIPSAssembler.h b/JavaScriptCore/assembler/MIPSAssembler.h
new file mode 100644
index 0000000..ea35268
--- /dev/null
+++ b/JavaScriptCore/assembler/MIPSAssembler.h
@@ -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
diff --git a/JavaScriptCore/assembler/MacroAssembler.h b/JavaScriptCore/assembler/MacroAssembler.h
index 76bd205..ce1be78 100644
--- a/JavaScriptCore/assembler/MacroAssembler.h
+++ b/JavaScriptCore/assembler/MacroAssembler.h
@@ -26,8 +26,6 @@
#ifndef MacroAssembler_h
#define MacroAssembler_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER)
#if CPU(ARM_THUMB2)
@@ -38,6 +36,12 @@ namespace JSC { typedef MacroAssemblerARMv7 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; };
@@ -327,6 +331,11 @@ public:
{
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
};
diff --git a/JavaScriptCore/assembler/MacroAssemblerARM.h b/JavaScriptCore/assembler/MacroAssemblerARM.h
index 21b8de8..52c4fa2 100644
--- a/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -28,8 +28,6 @@
#ifndef MacroAssemblerARM_h
#define MacroAssemblerARM_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER) && CPU(ARM_TRADITIONAL)
#include "ARMAssembler.h"
@@ -214,6 +212,11 @@ public:
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);
@@ -359,6 +362,12 @@ public:
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);
@@ -422,6 +431,12 @@ public:
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));
@@ -530,6 +545,13 @@ public:
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));
diff --git a/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index 532a9cf..3d08f0e 100644
--- a/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -1,5 +1,6 @@
/*
* 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
@@ -26,8 +27,6 @@
#ifndef MacroAssemblerARMv7_h
#define MacroAssemblerARMv7_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER)
#include "ARMv7Assembler.h"
@@ -368,6 +367,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)
@@ -404,6 +417,11 @@ public:
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);
@@ -793,6 +811,19 @@ public:
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));
@@ -823,6 +854,21 @@ public:
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());
@@ -973,6 +1019,14 @@ public:
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)
{
diff --git a/JavaScriptCore/assembler/MacroAssemblerCodeRef.h b/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
index cae8bf6..543b0fa 100644
--- a/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
+++ b/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
@@ -26,8 +26,6 @@
#ifndef MacroAssemblerCodeRef_h
#define MacroAssemblerCodeRef_h
-#include <wtf/Platform.h>
-
#include "ExecutableAllocator.h"
#include "PassRefPtr.h"
#include "RefPtr.h"
diff --git a/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/JavaScriptCore/assembler/MacroAssemblerMIPS.h
new file mode 100644
index 0000000..9853c34
--- /dev/null
+++ b/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -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
diff --git a/JavaScriptCore/assembler/MacroAssemblerX86.h b/JavaScriptCore/assembler/MacroAssemblerX86.h
index ca7c31a..0366541 100644
--- a/JavaScriptCore/assembler/MacroAssemblerX86.h
+++ b/JavaScriptCore/assembler/MacroAssemblerX86.h
@@ -26,8 +26,6 @@
#ifndef MacroAssemblerX86_h
#define MacroAssemblerX86_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER) && CPU(X86)
#include "MacroAssemblerX86Common.h"
diff --git a/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index 449df86..27c2f15 100644
--- a/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -26,8 +26,6 @@
#ifndef MacroAssemblerX86Common_h
#define MacroAssemblerX86Common_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER)
#include "X86Assembler.h"
@@ -620,6 +618,12 @@ 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);
@@ -717,6 +721,26 @@ public:
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()
{
@@ -836,6 +860,13 @@ public:
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));
@@ -917,10 +948,11 @@ public:
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
- 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.movzbl_rr(dest, dest);
}
void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
diff --git a/JavaScriptCore/assembler/MacroAssemblerX86_64.h b/JavaScriptCore/assembler/MacroAssemblerX86_64.h
index ec93f8c..339eaa4 100644
--- a/JavaScriptCore/assembler/MacroAssemblerX86_64.h
+++ b/JavaScriptCore/assembler/MacroAssemblerX86_64.h
@@ -26,8 +26,6 @@
#ifndef MacroAssemblerX86_64_h
#define MacroAssemblerX86_64_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER) && CPU(X86_64)
#include "MacroAssemblerX86Common.h"
@@ -411,6 +409,14 @@ public:
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);
diff --git a/JavaScriptCore/assembler/RepatchBuffer.h b/JavaScriptCore/assembler/RepatchBuffer.h
index 89cbf06..72cf6b2 100644
--- a/JavaScriptCore/assembler/RepatchBuffer.h
+++ b/JavaScriptCore/assembler/RepatchBuffer.h
@@ -26,8 +26,6 @@
#ifndef RepatchBuffer_h
#define RepatchBuffer_h
-#include <wtf/Platform.h>
-
#if ENABLE(ASSEMBLER)
#include <MacroAssembler.h>
diff --git a/JavaScriptCore/assembler/X86Assembler.h b/JavaScriptCore/assembler/X86Assembler.h
index ab3d05f..14a02f7 100644
--- a/JavaScriptCore/assembler/X86Assembler.h
+++ b/JavaScriptCore/assembler/X86Assembler.h
@@ -26,8 +26,6 @@
#ifndef X86Assembler_h
#define X86Assembler_h
-#include <wtf/Platform.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,
+ OP_GROUP1_EbIb = 0x80,
OP_GROUP1_EvIz = 0x81,
OP_GROUP1_EvIb = 0x83,
OP_TEST_EvGv = 0x85,
@@ -760,7 +759,7 @@ public:
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)) {
@@ -771,6 +770,18 @@ public:
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)
{
@@ -890,6 +901,18 @@ public:
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)
{
diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp
index 68debb2..8e77e12 100644
--- a/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -89,25 +89,6 @@ CString CodeBlock::registerName(ExecState* exec, int r) const
return makeString("r", UString::from(r)).UTF8String();
}
-static UString regexpToSourceString(RegExp* regExp)
-{
- char postfix[5] = { '/', 0, 0, 0, 0 };
- int index = 1;
- if (regExp->global())
- postfix[index++] = 'g';
- if (regExp->ignoreCase())
- postfix[index++] = 'i';
- if (regExp->multiline())
- postfix[index] = 'm';
-
- return makeString("/", regExp->pattern(), postfix);
-}
-
-static CString regexpName(int re, RegExp* regexp)
-{
- return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String();
-}
-
static UString pointerToSourceString(void* p)
{
char buffer[2 + 2 * sizeof(void*) + 1]; // 0x [two characters per byte] \0
@@ -141,7 +122,7 @@ void CodeBlock::printUnaryOp(ExecState* exec, int location, Vector<Instruction>:
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
@@ -149,14 +130,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;
- 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;
- 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
@@ -164,7 +145,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;
- 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;
}
@@ -173,7 +154,7 @@ void CodeBlock::printPutByIdOp(ExecState* exec, int location, Vector<Instruction
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;
}
@@ -223,32 +204,32 @@ static unsigned instructionOffsetForNth(ExecState* exec, const Vector<Instructio
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:
- 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:
- 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:
- 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:
- 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:
- 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:
- 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:
- 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");
@@ -277,7 +258,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();
- 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
@@ -294,15 +275,15 @@ void CodeBlock::printStructures(const Instruction* vPC) const
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)) {
- 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)) {
- 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)) {
@@ -364,15 +345,6 @@ void CodeBlock::dump(ExecState* exec) const
} while (i < m_constantRegisters.size());
}
- if (m_rareData && !m_rareData->m_regexps.isEmpty()) {
- printf("\nm_regexps:\n");
- size_t i = 0;
- do {
- printf(" re%u = %s\n", static_cast<unsigned>(i), regexpToSourceString(m_rareData->m_regexps[i].get()).ascii());
- ++i;
- } while (i < m_rareData->m_regexps.size());
- }
-
#if ENABLE(JIT)
if (!m_globalResolveInfos.isEmpty() || !m_structureStubInfos.isEmpty())
printf("\nStructures:\n");
@@ -482,7 +454,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
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: {
@@ -495,31 +467,25 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
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;
- 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;
- printf("[%4d] new_array\t %s, %s, %d\n", location, registerName(exec, dst).c_str(), registerName(exec, argv).c_str(), argc);
- 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_array\t %s, %s, %d\n", location, registerName(exec, dst).data(), registerName(exec, argv).data(), argc);
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: {
@@ -560,12 +526,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
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;
- 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: {
@@ -644,7 +610,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;
- 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: {
@@ -682,21 +648,21 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
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;
- 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;
- 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;
}
@@ -704,41 +670,41 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
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;
- 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;
- 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;
- 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;
- 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;
- 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: {
@@ -785,6 +751,26 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
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;
@@ -817,14 +803,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;
- 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;
- 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: {
@@ -835,14 +821,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;
- 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;
- 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: {
@@ -852,28 +838,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;
- 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;
- 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;
- 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;
- 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: {
@@ -914,75 +900,75 @@ 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;
- 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;
- 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;
- 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;
- 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;
- 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_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;
- 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;
- 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;
- 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;
- 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;
- 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: {
@@ -990,7 +976,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;
- 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: {
@@ -998,7 +984,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;
- 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: {
@@ -1006,7 +992,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;
- 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: {
@@ -1015,7 +1001,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
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: {
@@ -1024,7 +1010,7 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
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: {
@@ -1034,26 +1020,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;
- 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;
- 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;
- 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;
- 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: {
@@ -1062,7 +1048,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;
- 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;
}
@@ -1070,13 +1056,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;
- 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;
- 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: {
@@ -1087,7 +1073,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;
- 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: {
@@ -1098,30 +1084,30 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
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;
- 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;
- 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;
- 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;
- 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: {
@@ -1133,17 +1119,17 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
}
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;
- 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;
- 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;
}
}
@@ -1301,6 +1287,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, PassR
#endif
, m_needsFullScopeChain(ownerExecutable->needsActivation())
, m_usesEval(ownerExecutable->usesEval())
+ , m_usesArguments(false)
, m_isNumericCompareFunction(false)
, m_codeType(codeType)
, m_source(sourceProvider)
@@ -1375,7 +1362,7 @@ void CodeBlock::derefStructures(Instruction* vPC) const
{
Interpreter* interpreter = m_globalData->interpreter;
- if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_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;
}
@@ -1422,7 +1409,7 @@ void CodeBlock::refStructures(Instruction* vPC) const
{
Interpreter* interpreter = m_globalData->interpreter;
- if (vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_self) || vPC[0].u.opcode == interpreter->getOpcode(op_get_by_id_getter_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;
}
@@ -1686,7 +1673,6 @@ void CodeBlock::shrinkToFit()
if (m_rareData) {
m_rareData->m_exceptionHandlers.shrinkToFit();
- m_rareData->m_regexps.shrinkToFit();
m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
m_rareData->m_characterSwitchJumpTables.shrinkToFit();
m_rareData->m_stringSwitchJumpTables.shrinkToFit();
diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h
index d92dc9d..1bbb265 100644
--- a/JavaScriptCore/bytecode/CodeBlock.h
+++ b/JavaScriptCore/bytecode/CodeBlock.h
@@ -102,9 +102,11 @@ namespace JSC {
struct CallLinkInfo {
CallLinkInfo()
: callee(0)
+ , position(0)
+ , hasSeenShouldRepatch(0)
{
}
-
+
unsigned bytecodeIndex;
CodeLocationNearCall callReturnLocation;
CodeLocationDataLabelPtr hotPathBegin;
@@ -456,10 +458,6 @@ namespace JSC {
unsigned addFunctionExpr(NonNullPassRefPtr<FunctionExecutable> n) { unsigned size = m_functionExprs.size(); m_functionExprs.append(n); return size; }
FunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
- unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
- RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
-
-
// Jump Tables
size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
@@ -554,9 +552,6 @@ namespace JSC {
struct RareData : FastAllocBase {
Vector<HandlerInfo> m_exceptionHandlers;
- // Rare Constants
- Vector<RefPtr<RegExp> > m_regexps;
-
// Jump Tables
Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
Vector<SimpleJumpTable> m_characterSwitchJumpTables;
diff --git a/JavaScriptCore/bytecode/EvalCodeCache.h b/JavaScriptCore/bytecode/EvalCodeCache.h
index a036dd4..27c479d 100644
--- a/JavaScriptCore/bytecode/EvalCodeCache.h
+++ b/JavaScriptCore/bytecode/EvalCodeCache.h
@@ -37,6 +37,7 @@
#include "UString.h"
#include <wtf/HashMap.h>
#include <wtf/RefPtr.h>
+#include <wtf/text/StringHash.h>
namespace JSC {
diff --git a/JavaScriptCore/bytecode/Instruction.h b/JavaScriptCore/bytecode/Instruction.h
index bcef7fb..ab6659f 100644
--- a/JavaScriptCore/bytecode/Instruction.h
+++ b/JavaScriptCore/bytecode/Instruction.h
@@ -31,6 +31,7 @@
#include "MacroAssembler.h"
#include "Opcode.h"
+#include "PropertySlot.h"
#include "Structure.h"
#include <wtf/VectorTraits.h>
@@ -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(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
union {
Opcode opcode;
@@ -152,6 +154,7 @@ namespace JSC {
StructureChain* structureChain;
JSCell* jsCell;
PolymorphicAccessStructureList* polymorphicStructures;
+ PropertySlot::GetValueFunc getterFunc;
} u;
};
diff --git a/JavaScriptCore/bytecode/JumpTable.cpp b/JavaScriptCore/bytecode/JumpTable.cpp
index 175c1b3..ef7098b 100644
--- a/JavaScriptCore/bytecode/JumpTable.cpp
+++ b/JavaScriptCore/bytecode/JumpTable.cpp
@@ -30,6 +30,8 @@
#include "config.h"
#include "JumpTable.h"
+#include <wtf/text/StringHash.h>
+
namespace JSC {
int32_t SimpleJumpTable::offsetForValue(int32_t value, int32_t defaultOffset)
diff --git a/JavaScriptCore/bytecode/Opcode.h b/JavaScriptCore/bytecode/Opcode.h
index 56555f3..0a7f3fa 100644
--- a/JavaScriptCore/bytecode/Opcode.h
+++ b/JavaScriptCore/bytecode/Opcode.h
@@ -46,7 +46,6 @@ namespace JSC {
\
macro(op_new_object, 2) \
macro(op_new_array, 4) \
- macro(op_new_regexp, 3) \
macro(op_mov, 3) \
\
macro(op_not, 3) \
@@ -109,6 +108,11 @@ namespace JSC {
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) \
diff --git a/JavaScriptCore/bytecode/SamplingTool.cpp b/JavaScriptCore/bytecode/SamplingTool.cpp
index 3f0babc..8522e45 100644
--- a/JavaScriptCore/bytecode/SamplingTool.cpp
+++ b/JavaScriptCore/bytecode/SamplingTool.cpp
@@ -337,7 +337,7 @@ void SamplingTool::dump(ExecState* exec)
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);
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
index f2193b0..aa5c5f9 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp
@@ -34,6 +34,8 @@
#include "PrototypeFunction.h"
#include "JSFunction.h"
#include "Interpreter.h"
+#include "RegExp.h"
+#include "RegExpObject.h"
#include "UString.h"
using namespace std;
@@ -827,11 +829,6 @@ RegisterID* BytecodeGenerator::addConstantValue(JSValue v)
return &m_constantPoolRegisters[index];
}
-unsigned BytecodeGenerator::addRegExp(RegExp* r)
-{
- return m_codeBlock->addRegExp(r);
-}
-
RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
{
emitOpcode(op_mov);
@@ -982,6 +979,12 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& ident
return emitLoad(dst, JSValue(stringInMap));
}
+RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, RegExp* regExp)
+{
+ JSValue jsRegExp = new (globalData()) RegExpObject(m_scopeChain->globalObject()->regExpStructure(), regExp);
+ return emitLoad(dst, jsRegExp);
+}
+
RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
{
RegisterID* constantID = addConstantValue(v);
@@ -1361,15 +1364,6 @@ RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode
return dst;
}
-RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
-{
- emitOpcode(op_new_regexp);
- instructions().append(dst->index());
- instructions().append(addRegExp(regExp));
- return dst;
-}
-
-
RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
{
FunctionBodyNode* function = n->body();
@@ -1942,7 +1936,7 @@ static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t
UString::Rep* clause = static_cast<StringNode*>(node)->value().ustring().rep();
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;
diff --git a/JavaScriptCore/bytecompiler/BytecodeGenerator.h b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
index 8b6a425..919183e 100644
--- a/JavaScriptCore/bytecompiler/BytecodeGenerator.h
+++ b/JavaScriptCore/bytecompiler/BytecodeGenerator.h
@@ -264,6 +264,7 @@ namespace JSC {
RegisterID* emitLoad(RegisterID* dst, bool);
RegisterID* emitLoad(RegisterID* dst, double);
RegisterID* emitLoad(RegisterID* dst, const Identifier&);
+ RegisterID* emitLoad(RegisterID* dst, RegExp* regExp);
RegisterID* emitLoad(RegisterID* dst, JSValue);
RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
@@ -276,7 +277,6 @@ namespace JSC {
RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode* body);
RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func);
- RegisterID* emitNewRegExp(RegisterID* dst, RegExp* regExp);
RegisterID* emitMove(RegisterID* dst, RegisterID* src);
@@ -446,7 +446,6 @@ namespace JSC {
unsigned addConstant(const Identifier&);
RegisterID* addConstantValue(JSValue);
- unsigned addRegExp(RegExp*);
PassRefPtr<FunctionExecutable> makeFunction(ExecState* exec, FunctionBodyNode* body)
{
diff --git a/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 4162873..aaf2dd1 100644
--- a/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -149,7 +149,7 @@ RegisterID* RegExpNode::emitBytecode(BytecodeGenerator& generator, RegisterID* d
return emitThrowError(generator, SyntaxError, "Invalid regular expression: %s", regExp->errorMessage());
if (dst == generator.ignoredResult())
return 0;
- return generator.emitNewRegExp(generator.finalDestination(dst), regExp.get());
+ return generator.emitLoad(generator.finalDestination(dst), regExp.get());
}
// ------------------------------ ThisNode -------------------------------------
@@ -1699,7 +1699,7 @@ static void processClauseList(ClauseListNode* list, Vector<ExpressionNode*, 8>&
}
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)
diff --git a/JavaScriptCore/config.h b/JavaScriptCore/config.h
index d5fdfe9..791564a 100644
--- a/JavaScriptCore/config.h
+++ b/JavaScriptCore/config.h
@@ -25,7 +25,7 @@
#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
@@ -75,6 +75,12 @@
#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
diff --git a/JavaScriptCore/create_hash_table b/JavaScriptCore/create_hash_table
index 4184500..77463fb 100755
--- a/JavaScriptCore/create_hash_table
+++ b/JavaScriptCore/create_hash_table
@@ -252,18 +252,21 @@ sub output() {
foreach my $key (@keys) {
my $firstValue = "";
my $secondValue = "";
+ my $castStr = "";
if ($values[$i]{"type"} eq "Function") {
+ $castStr = "static_cast<NativeFunction>";
$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";
}
- print " { \"$key\", $attrs[$i], (intptr_t)$firstValue, (intptr_t)$secondValue },\n";
+ print " { \"$key\", $attrs[$i], (intptr_t)" . $castStr . "($firstValue), (intptr_t)$secondValue },\n";
$i++;
}
print " { 0, 0, 0, 0 }\n";
diff --git a/JavaScriptCore/create_regex_tables b/JavaScriptCore/create_regex_tables
new file mode 100644
index 0000000..b436eee
--- /dev/null
+++ b/JavaScriptCore/create_regex_tables
@@ -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/JavaScriptCore/interpreter/Interpreter.cpp b/JavaScriptCore/interpreter/Interpreter.cpp
index 6dbbcf9..40f6458 100644
--- a/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/JavaScriptCore/interpreter/Interpreter.cpp
@@ -522,8 +522,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);
}
-
- 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.
}
@@ -579,8 +580,8 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
{
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();
}
@@ -640,8 +641,8 @@ JSValue Interpreter::execute(FunctionExecutable* functionExecutable, CallFrame*
{
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();
}
@@ -702,8 +703,8 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
{
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();
}
@@ -778,8 +779,8 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSObjec
{
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();
}
@@ -1030,8 +1031,20 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
// Cache hit: Specialize instruction and ref Structures.
if (slot.slotBase() == baseValue) {
- vPC[0] = slot.isGetter() ? getOpcode(op_get_by_id_getter_self) : 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;
@@ -1056,10 +1069,22 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
}
ASSERT(!baseObject->structure()->isUncacheableDictionary());
-
- vPC[0] = slot.isGetter() ? getOpcode(op_get_by_id_getter_proto) : 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[6] = offset;
codeBlock->refStructures(vPC);
return;
@@ -1072,11 +1097,24 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
return;
}
- vPC[0] = slot.isGetter() ? getOpcode(op_get_by_id_getter_chain) : 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[7] = offset;
codeBlock->refStructures(vPC);
}
@@ -1137,7 +1175,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#define CHECK_FOR_TIMEOUT() \
if (!--tickCount) { \
- if (globalData->timeoutChecker.didTimeOut(callFrame)) { \
+ if (globalData->terminator.shouldTerminate() || globalData->timeoutChecker.didTimeOut(callFrame)) { \
exceptionValue = jsNull(); \
goto vm_throw; \
} \
@@ -1199,20 +1237,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
vPC += OPCODE_LENGTH(op_new_array);
NEXT_INSTRUCTION();
}
- DEFINE_OPCODE(op_new_regexp) {
- /* new_regexp dst(r) regExp(re)
-
- Constructs a new RegExp instance using the original
- constructor from regexp regExp, and puts the result in
- register dst.
- */
- int dst = vPC[1].u.operand;
- int regExp = vPC[2].u.operand;
- callFrame->r(dst) = JSValue(new (globalData) RegExpObject(callFrame->scopeChain()->globalObject->regExpStructure(), callFrame->codeBlock()->regexp(regExp)));
-
- vPC += OPCODE_LENGTH(op_new_regexp);
- NEXT_INSTRUCTION();
- }
DEFINE_OPCODE(op_mov) {
/* mov dst(r) src(r)
@@ -1483,7 +1507,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
*/
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));
@@ -2207,6 +2231,48 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#if HAVE(COMPUTED_GOTO)
skip_id_getter_proto:
#endif
+#if HAVE(COMPUTED_GOTO)
+ 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 HAVE(COMPUTED_GOTO)
+ 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();
@@ -2235,6 +2301,20 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
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)
@@ -2324,6 +2404,43 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#if HAVE(COMPUTED_GOTO)
skip_id_getter_self:
#endif
+#if HAVE(COMPUTED_GOTO)
+ 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 HAVE(COMPUTED_GOTO)
+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)
@@ -2379,7 +2496,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
JSObject* getter = getterSetter->getter();
CallData callData;
CallType callType = getter->getCallData(callData);
- JSValue result = call(callFrame, getter, callType, callData, asObject(baseCell), ArgList());
+ JSValue result = call(callFrame, getter, callType, callData, baseValue, ArgList());
CHECK_FOR_EXCEPTION();
callFrame->r(dst) = result;
} else
@@ -2399,6 +2516,58 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
#if HAVE(COMPUTED_GOTO)
skip_id_getter_chain:
#endif
+#if HAVE(COMPUTED_GOTO)
+ 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 HAVE(COMPUTED_GOTO)
+ 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)
@@ -3085,7 +3254,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (value->length() != 1)
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();
}
diff --git a/JavaScriptCore/interpreter/Interpreter.h b/JavaScriptCore/interpreter/Interpreter.h
index e17b055..cf8b342 100644
--- a/JavaScriptCore/interpreter/Interpreter.h
+++ b/JavaScriptCore/interpreter/Interpreter.h
@@ -64,7 +64,7 @@ namespace JSC {
WillExecuteStatement
};
- enum { MaxMainThreadReentryDepth = 256, MaxSecondaryThreadReentryDepth = 32 };
+ enum { MaxLargeThreadReentryDepth = 256, MaxSmallThreadReentryDepth = 32 };
class Interpreter : public FastAllocBase {
friend class JIT;
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
index 1fb8ff7..8f46dee 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -43,6 +43,10 @@
#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
@@ -190,6 +194,32 @@ public:
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)
{
diff --git a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
index dd1db4e..4d3c847 100644
--- a/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
+++ b/JavaScriptCore/jit/ExecutableAllocatorFixedVMPool.cpp
@@ -27,10 +27,10 @@
#include "ExecutableAllocator.h"
-#include <errno.h>
-
#if ENABLE(ASSEMBLER) && OS(DARWIN) && CPU(X86_64)
+#include <errno.h>
+
#include "TCSpinLock.h"
#include <mach/mach_init.h>
#include <mach/vm_map.h>
diff --git a/JavaScriptCore/jit/JIT.cpp b/JavaScriptCore/jit/JIT.cpp
index 78c5153..ec23d8c 100644
--- a/JavaScriptCore/jit/JIT.cpp
+++ b/JavaScriptCore/jit/JIT.cpp
@@ -275,7 +275,6 @@ void JIT::privateCompileMainPass()
DEFINE_OP(op_new_func)
DEFINE_OP(op_new_func_exp)
DEFINE_OP(op_new_object)
- DEFINE_OP(op_new_regexp)
DEFINE_OP(op_next_pname)
DEFINE_OP(op_not)
DEFINE_OP(op_nstricteq)
@@ -327,6 +326,11 @@ void JIT::privateCompileMainPass()
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:
diff --git a/JavaScriptCore/jit/JIT.h b/JavaScriptCore/jit/JIT.h
index bfbb1ee..e757112 100644
--- a/JavaScriptCore/jit/JIT.h
+++ b/JavaScriptCore/jit/JIT.h
@@ -26,8 +26,6 @@
#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
@@ -268,6 +266,28 @@ namespace JSC {
static const FPRegisterID fpRegT0 = ARMRegisters::d0;
static const FPRegisterID fpRegT1 = ARMRegisters::d1;
static const FPRegisterID fpRegT2 = ARMRegisters::d2;
+#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;
#else
#error "JIT not supported on this platform."
#endif
@@ -283,32 +303,32 @@ namespace JSC {
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.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.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.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.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.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)
@@ -354,11 +374,11 @@ namespace JSC {
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 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);
void privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* data, TrampolineStructure *trampolines);
@@ -686,6 +706,48 @@ namespace JSC {
// 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)
@@ -759,7 +821,6 @@ namespace JSC {
void emit_op_new_func(Instruction*);
void emit_op_new_func_exp(Instruction*);
void emit_op_new_object(Instruction*);
- void emit_op_new_regexp(Instruction*);
void emit_op_get_pnames(Instruction*);
void emit_op_next_pname(Instruction*);
void emit_op_not(Instruction*);
diff --git a/JavaScriptCore/jit/JITArithmetic.cpp b/JavaScriptCore/jit/JITArithmetic.cpp
index 2f2ffe3..2e1ff40 100644
--- a/JavaScriptCore/jit/JITArithmetic.cpp
+++ b/JavaScriptCore/jit/JITArithmetic.cpp
@@ -56,8 +56,7 @@ void JIT::emit_op_negate(Instruction* currentInstruction)
emitLoad(src, regT1, regT0);
Jump srcNotInt = branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag));
- addSlowCase(branch32(Equal, regT0, Imm32(0)));
-
+ addSlowCase(branchTest32(Zero, regT0, Imm32(0x7fffffff)));
neg32(regT0);
emitStoreInt32(dst, regT0, (dst == src));
@@ -78,7 +77,7 @@ void JIT::emitSlow_op_negate(Instruction* currentInstruction, Vector<SlowCaseEnt
{
unsigned dst = currentInstruction[1].u.operand;
- linkSlowCase(iter); // 0 check
+ linkSlowCase(iter); // 0x7fffffff check
linkSlowCase(iter); // double check
JITStubCall stubCall(this, cti_op_negate);
diff --git a/JavaScriptCore/jit/JITCall.cpp b/JavaScriptCore/jit/JITCall.cpp
index 179aad7..da603bd 100644
--- a/JavaScriptCore/jit/JITCall.cpp
+++ b/JavaScriptCore/jit/JITCall.cpp
@@ -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);
- 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)
diff --git a/JavaScriptCore/jit/JITCode.h b/JavaScriptCore/jit/JITCode.h
index 69cf167..5d889b5 100644
--- a/JavaScriptCore/jit/JITCode.h
+++ b/JavaScriptCore/jit/JITCode.h
@@ -26,8 +26,6 @@
#ifndef JITCode_h
#define JITCode_h
-#include <wtf/Platform.h>
-
#if ENABLE(JIT)
#include "CallFrame.h"
diff --git a/JavaScriptCore/jit/JITInlineMethods.h b/JavaScriptCore/jit/JITInlineMethods.h
index 5af7565..96a2e5b 100644
--- a/JavaScriptCore/jit/JITInlineMethods.h
+++ b/JavaScriptCore/jit/JITInlineMethods.h
@@ -26,7 +26,6 @@
#ifndef JITInlineMethods_h
#define JITInlineMethods_h
-#include <wtf/Platform.h>
#if ENABLE(JIT)
@@ -161,6 +160,23 @@ ALWAYS_INLINE void JIT::restoreReturnAddressBeforeReturn(Address address)
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)
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp
index c470495..0dd6a40 100644
--- a/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/JavaScriptCore/jit/JITOpcodes.cpp
@@ -1,5 +1,6 @@
/*
* 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
@@ -282,6 +283,33 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
// 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);
@@ -290,7 +318,7 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
// Setup arg4:
storePtr(regT3, Address(stackPointerRegister, 8));
- // Setup arg3
+ // 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));
@@ -310,6 +338,8 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
load32(Address(stackPointerRegister, 20), regT1);
addPtr(Imm32(sizeof(ArgList) + 16 + 8), stackPointerRegister);
+#endif // OS(WINCE)
+
#endif
// Check for an exception
@@ -486,7 +516,7 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
// 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.
@@ -839,7 +869,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);
- 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();
@@ -866,7 +896,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);
- 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();
@@ -1143,13 +1173,6 @@ void JIT::emit_op_new_func_exp(Instruction* currentInstruction)
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;
@@ -1179,7 +1202,7 @@ void JIT::emit_op_get_pnames(Instruction* currentInstruction)
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)));
+ 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
@@ -1458,7 +1481,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
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)));
+ 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);
}
@@ -1764,7 +1787,30 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
// 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:
@@ -1779,6 +1825,57 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable
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."
@@ -1938,7 +2035,7 @@ void JIT::emit_op_instanceof(Instruction* currentInstruction)
// 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.
@@ -2099,7 +2196,7 @@ void JIT::emit_op_construct_verify(Instruction* currentInstruction)
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)));
}
@@ -2208,7 +2305,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);
- 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
@@ -2229,7 +2326,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);
- 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
@@ -2342,13 +2439,6 @@ void JIT::emit_op_bitxor(Instruction* currentInstruction)
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);
@@ -2385,7 +2475,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(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
@@ -2536,7 +2626,7 @@ void JIT::emit_op_to_jsnumber(Instruction* currentInstruction)
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);
@@ -2647,7 +2737,7 @@ void JIT::emit_op_eq_null(Instruction* currentInstruction)
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();
@@ -2672,7 +2762,7 @@ void JIT::emit_op_neq_null(Instruction* currentInstruction)
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();
@@ -2732,7 +2822,7 @@ void JIT::emit_op_convert_this(Instruction* currentInstruction)
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)));
}
diff --git a/JavaScriptCore/jit/JITPropertyAccess.cpp b/JavaScriptCore/jit/JITPropertyAccess.cpp
index 151bb03..3399f03 100644
--- a/JavaScriptCore/jit/JITPropertyAccess.cpp
+++ b/JavaScriptCore/jit/JITPropertyAccess.cpp
@@ -32,6 +32,7 @@
#if ENABLE(JIT)
#include "CodeBlock.h"
+#include "GetterSetter.h"
#include "JITInlineMethods.h"
#include "JITStubCall.h"
#include "JSArray.h"
@@ -695,7 +696,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
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!)
@@ -713,11 +714,28 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
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();
-
LinkBuffer patchBuffer(this, m_codeBlock->executablePool());
// Use the patch information to link the failure cases back to the original slow case routine.
@@ -728,6 +746,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));
+ 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;
@@ -741,14 +765,43 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
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);
- 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());
+ 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)
@@ -770,7 +823,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
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!)
@@ -788,13 +841,38 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
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());
+ 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);
@@ -815,10 +893,9 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
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);
-
JumpList bucketsOfFail;
// Check eax is an object of the right Structure.
@@ -842,11 +919,36 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
#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());
+
+ 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;
@@ -869,10 +971,10 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
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);
-
+
JumpList bucketsOfFail;
// Check eax is an object of the right Structure.
@@ -896,11 +998,36 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
}
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());
+ 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));
diff --git a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
index f9e323d..ec33026 100644
--- a/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
+++ b/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
@@ -718,7 +718,7 @@ void JIT::privateCompilePatchGetArrayLength(ReturnAddressPtr returnAddress)
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)
{
// regT0 holds a JSCell*
@@ -736,9 +736,26 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
#else
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
#endif
-
- // Checks out okay! - getDirectOffset
- compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+ 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();
@@ -751,7 +768,14 @@ 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));
-
+
+ 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;
@@ -766,16 +790,43 @@ void JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* str
}
-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)
{
// regT0 holds a JSCell*
-
Jump failureCase = checkStructure(regT0, structure);
- compileGetDirectOffset(regT0, regT1, regT0, structure, cachedOffset);
+ 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)
@@ -785,7 +836,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
// 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();
@@ -797,7 +848,7 @@ void JIT::privateCompileGetByIdSelfList(StructureStubInfo* stubInfo, Polymorphic
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)
{
// regT0 holds a JSCell*
@@ -817,12 +868,35 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure));
#endif
- compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+ 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);
@@ -843,10 +917,9 @@ void JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Polymorphi
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)
{
// regT0 holds a JSCell*
-
ASSERT(count);
JumpList bucketsOfFail;
@@ -872,11 +945,35 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
}
ASSERT(protoObject);
- compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+ 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;
@@ -898,10 +995,9 @@ void JIT::privateCompileGetByIdChainList(StructureStubInfo* stubInfo, Polymorphi
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)
{
// regT0 holds a JSCell*
-
ASSERT(count);
JumpList bucketsOfFail;
@@ -927,11 +1023,34 @@ void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* str
}
ASSERT(protoObject);
- compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset);
+ 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));
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index bf430a6..c32f2ce 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -38,6 +38,7 @@
#include "Collector.h"
#include "Debugger.h"
#include "ExceptionHelpers.h"
+#include "GetterSetter.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
-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 0x64
#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)
@@ -543,102 +465,115 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#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"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\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"
- "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"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\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"
- "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"
+".set noreorder" "\n"
+".set nomacro" "\n"
+".set nomips16" "\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, #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"
-);
-
-#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"
+".ent " SYMBOL_STRING(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)
@@ -749,6 +684,108 @@ extern "C" {
#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
@@ -763,18 +800,38 @@ JITThunks::JITThunks(JSGlobalData* globalData)
// 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.
- 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
}
@@ -856,11 +913,10 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
}
// Uncacheable: give up.
- if (!slot.isCacheableValue()) {
+ if (!slot.isCacheable()) {
ctiPatchCallByReturnAddress(codeBlock, returnAddress, FunctionPtr(cti_op_get_by_id_generic));
return;
}
- ASSERT(!slot.isGetter());
JSCell* baseCell = asCell(baseValue);
Structure* structure = baseCell->structure();
@@ -875,8 +931,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);
-
- 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;
}
@@ -902,7 +960,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
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;
}
@@ -915,7 +973,7 @@ NEVER_INLINE void JITThunks::tryCacheGetByID(CallFrame* callFrame, CodeBlock* co
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)
@@ -1025,22 +1083,73 @@ static NEVER_INLINE void throwStackOverflowError(CallFrame* callFrame, JSGlobalD
".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" \
- "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) \
-#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
-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" { \
@@ -1148,15 +1257,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_inc)
DEFINE_STUB_FUNCTION(int, timeout_check)
{
STUB_INIT_STACK_FRAME(stackFrame);
-
+
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();
}
-
+
return timeoutChecker.ticksUntilNextCheck();
}
@@ -1375,7 +1487,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
CHECK_FOR_EXCEPTION();
if (baseValue.isCell()
- && slot.isCacheableValue()
+ && slot.isCacheable()
&& !asCell(baseValue)->structure()->isUncacheableDictionary()
&& slot.slotBase() == baseValue) {
@@ -1397,7 +1509,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail)
stubInfo->u.getByIdSelfList.listSize++;
}
- JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), slot.cachedOffset());
+ JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), ident, slot, slot.cachedOffset());
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic));
@@ -1435,6 +1547,37 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(Str
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);
@@ -1448,7 +1591,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
CHECK_FOR_EXCEPTION();
- if (!baseValue.isCell() || !slot.isCacheableValue() || asCell(baseValue)->structure()->isDictionary()) {
+ if (!baseValue.isCell() || !slot.isCacheable() || asCell(baseValue)->structure()->isDictionary()) {
ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail));
return JSValue::encode(result);
}
@@ -1476,7 +1619,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
int listIndex;
PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
- JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), offset);
+ JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset);
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
@@ -1486,7 +1629,7 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list)
PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex);
StructureChain* protoChain = structure->prototypeChain(callFrame);
- JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, offset);
+ JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset);
if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1))
ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full));
@@ -2518,10 +2661,9 @@ DEFINE_STUB_FUNCTION(int, op_eq)
#endif // USE(JSVALUE32_64)
}
-#if USE(JSVALUE32_64)
-
DEFINE_STUB_FUNCTION(int, op_eq_strings)
{
+#if USE(JSVALUE32_64)
STUB_INIT_STACK_FRAME(stackFrame);
JSString* string1 = stackFrame.args[0].jsString();
@@ -2530,9 +2672,12 @@ DEFINE_STUB_FUNCTION(int, op_eq_strings)
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
+}
DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
{
@@ -2713,13 +2858,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitxor)
return JSValue::encode(result);
}
-DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return new (stackFrame.globalData) RegExpObject(stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), stackFrame.args[0].regExp());
-}
-
DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
{
STUB_INIT_STACK_FRAME(stackFrame);
@@ -3025,7 +3163,7 @@ DEFINE_STUB_FUNCTION(void*, op_switch_char)
if (scrutinee.isString()) {
UString::Rep* value = asString(scrutinee)->value(callFrame).rep();
if (value->length() == 1)
- result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->data()[0]).executableAddress();
+ result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue(value->characters()[0]).executableAddress();
}
return result;
diff --git a/JavaScriptCore/jit/JITStubs.h b/JavaScriptCore/jit/JITStubs.h
index 17fd0d9..f419c8c 100644
--- a/JavaScriptCore/jit/JITStubs.h
+++ b/JavaScriptCore/jit/JITStubs.h
@@ -29,8 +29,6 @@
#ifndef JITStubs_h
#define JITStubs_h
-#include <wtf/Platform.h>
-
#include "MacroAssemblerCodeRef.h"
#include "Register.h"
@@ -108,10 +106,10 @@ namespace JSC {
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)
-#endif // COMPILER(MSVC)
+#endif // COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
struct JITStackFrame {
void* reserved; // Unused
JITStubArg args[6];
@@ -135,9 +133,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; }
};
-#if COMPILER(MSVC)
+#if COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
#pragma pack(pop)
-#endif // COMPILER(MSVC)
+#endif // COMPILER(MSVC) || (OS(WINDOWS) && COMPILER(GCC))
#elif CPU(ARM_THUMB2)
struct JITStackFrame {
void* reserved; // Unused
@@ -191,6 +189,30 @@ namespace JSC {
// 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
#error "JITStackFrame not defined for this platform."
#endif
@@ -276,6 +298,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_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);
@@ -326,7 +350,6 @@ extern "C" {
JSObject* JIT_STUB cti_op_new_func(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_new_func_exp(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_new_object(STUB_ARGS_DECLARATION);
- JSObject* JIT_STUB cti_op_new_regexp(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_push_activation(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_push_new_scope(STUB_ARGS_DECLARATION);
JSObject* JIT_STUB cti_op_push_scope(STUB_ARGS_DECLARATION);
@@ -334,9 +357,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);
-#if USE(JSVALUE32_64)
int JIT_STUB cti_op_eq_strings(STUB_ARGS_DECLARATION);
-#endif
int JIT_STUB cti_op_jless(STUB_ARGS_DECLARATION);
int JIT_STUB cti_op_jlesseq(STUB_ARGS_DECLARATION);
int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION);
diff --git a/JavaScriptCore/jsc.cpp b/JavaScriptCore/jsc.cpp
index 252fb96..ae47d55 100644
--- a/JavaScriptCore/jsc.cpp
+++ b/JavaScriptCore/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 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&);
@@ -177,7 +177,7 @@ JSValue JSC_HOST_CALL functionPrint(ExecState* exec, JSObject*, JSValue, const A
if (i)
putchar(' ');
- printf("%s", args.at(i).toString(exec).UTF8String().c_str());
+ printf("%s", args.at(i).toString(exec).UTF8String().data());
}
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)
{
- 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();
}
@@ -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;
- JSGlobalData* globalData = JSGlobalData::create().releaseRef();
+ JSGlobalData* globalData = JSGlobalData::create(ThreadStackTypeLarge).releaseRef();
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
- printf("%s\n", completion.value().toString(globalObject->globalExec()).UTF8String().c_str());
+ printf("%s\n", completion.value().toString(globalObject->globalExec()).UTF8String().data());
globalObject->globalExec()->clearException();
}
@@ -535,9 +535,9 @@ int jscmain(int argc, char** argv, JSGlobalData* globalData)
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) {
- 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;
}
diff --git a/JavaScriptCore/jsc.pro b/JavaScriptCore/jsc.pro
index 9bcf08b..420a3f1 100644
--- a/JavaScriptCore/jsc.pro
+++ b/JavaScriptCore/jsc.pro
@@ -8,13 +8,13 @@ CONFIG += building-libs
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
-isEmpty(OUTPUT_DIR):OUTPUT_DIR=$$PWD/..
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)
-
-*-g++*:QMAKE_CXXFLAGS_RELEASE -= -O2
-*-g++*:QMAKE_CXXFLAGS_RELEASE += -O3
+addJavaScriptCoreLib(.)
symbian {
TARGET.CAPABILITY = ReadUserData WriteUserData NetworkServices
diff --git a/JavaScriptCore/make-generated-sources.sh b/JavaScriptCore/make-generated-sources.sh
index 943a7cc..a6b0f63 100755
--- a/JavaScriptCore/make-generated-sources.sh
+++ b/JavaScriptCore/make-generated-sources.sh
@@ -3,6 +3,7 @@
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
diff --git a/JavaScriptCore/os-win32/stdint.h b/JavaScriptCore/os-win32/stdint.h
index 1d8787e..b5dff56 100644
--- a/JavaScriptCore/os-win32/stdint.h
+++ b/JavaScriptCore/os-win32/stdint.h
@@ -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(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
diff --git a/JavaScriptCore/parser/Grammar.y b/JavaScriptCore/parser/Grammar.y
index a017cff..4d6e7d1 100644
--- a/JavaScriptCore/parser/Grammar.y
+++ b/JavaScriptCore/parser/Grammar.y
@@ -1147,7 +1147,7 @@ ThrowStatement:
;
TryStatement:
- TRY Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->emptyIdentifier, false, 0, $4.m_node),
+ TRY Block FINALLY Block { $$ = createNodeDeclarationInfo<StatementNode*>(new (GLOBAL_DATA) TryNode(GLOBAL_DATA, $2.m_node, GLOBAL_DATA->propertyNames->nullIdentifier, false, 0, $4.m_node),
mergeDeclarationLists($2.m_varDeclarations, $4.m_varDeclarations),
mergeDeclarationLists($2.m_funcDeclarations, $4.m_funcDeclarations),
$2.m_features | $4.m_features,
@@ -1188,10 +1188,10 @@ FunctionDeclaration:
;
FunctionExpr:
- FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->emptyIdentifier, $5, GLOBAL_DATA->lexer->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); setStatementLocation($5, @4, @6); }
+ FUNCTION '(' ')' OPENBRACE FunctionBody CLOSEBRACE { $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $5, GLOBAL_DATA->lexer->sourceCode($4, $6, @4.first_line)), ClosureFeature, 0); setStatementLocation($5, @4, @6); }
| FUNCTION '(' FormalParameterList ')' OPENBRACE FunctionBody CLOSEBRACE
{
- $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->emptyIdentifier, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0);
+ $$ = createNodeInfo(new (GLOBAL_DATA) FuncExprNode(GLOBAL_DATA, GLOBAL_DATA->propertyNames->nullIdentifier, $6, GLOBAL_DATA->lexer->sourceCode($5, $7, @5.first_line), $3.m_node.head), $3.m_features | ClosureFeature, 0);
if ($3.m_features & ArgumentsFeature)
$6->setUsesArguments();
setStatementLocation($6, @5, @7);
@@ -1981,18 +1981,15 @@ static PropertyNode* makeGetterOrSetterPropertyNode(JSGlobalData* globalData, co
type = PropertyNode::Setter;
else
return 0;
- return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->emptyIdentifier, body, source, params), type);
+ return new (globalData) PropertyNode(globalData, name, new (globalData) FuncExprNode(globalData, globalData->propertyNames->nullIdentifier, body, source, params), type);
}
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);
diff --git a/JavaScriptCore/parser/NodeConstructors.h b/JavaScriptCore/parser/NodeConstructors.h
index fa8dd4b..dd3b981 100644
--- a/JavaScriptCore/parser/NodeConstructors.h
+++ b/JavaScriptCore/parser/NodeConstructors.h
@@ -741,7 +741,7 @@ namespace JSC {
inline ContinueNode::ContinueNode(JSGlobalData* globalData)
: StatementNode(globalData)
- , m_ident(globalData->propertyNames->emptyIdentifier)
+ , m_ident(globalData->propertyNames->nullIdentifier)
{
}
@@ -753,7 +753,7 @@ namespace JSC {
inline BreakNode::BreakNode(JSGlobalData* globalData)
: StatementNode(globalData)
- , m_ident(globalData->propertyNames->emptyIdentifier)
+ , m_ident(globalData->propertyNames->nullIdentifier)
{
}
@@ -877,7 +877,7 @@ namespace JSC {
inline ForInNode::ForInNode(JSGlobalData* globalData, ExpressionNode* l, ExpressionNode* expr, StatementNode* statement)
: StatementNode(globalData)
- , m_ident(globalData->propertyNames->emptyIdentifier)
+ , m_ident(globalData->propertyNames->nullIdentifier)
, m_init(0)
, m_lexpr(l)
, m_expr(expr)
diff --git a/JavaScriptCore/parser/Nodes.h b/JavaScriptCore/parser/Nodes.h
index c216ea8..7852165 100644
--- a/JavaScriptCore/parser/Nodes.h
+++ b/JavaScriptCore/parser/Nodes.h
@@ -1385,12 +1385,6 @@ namespace JSC {
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(); }
diff --git a/JavaScriptCore/parser/Parser.cpp b/JavaScriptCore/parser/Parser.cpp
index 56c96b4..48627df 100644
--- a/JavaScriptCore/parser/Parser.cpp
+++ b/JavaScriptCore/parser/Parser.cpp
@@ -27,9 +27,6 @@
#include "Lexer.h"
#include <wtf/HashSet.h>
#include <wtf/Vector.h>
-#include <memory>
-
-using std::auto_ptr;
#ifndef yyparse
extern int jscyyparse(void*);
diff --git a/JavaScriptCore/pcre/pcre_exec.cpp b/JavaScriptCore/pcre/pcre_exec.cpp
index 8ca2eb4..50973d0 100644
--- a/JavaScriptCore/pcre/pcre_exec.cpp
+++ b/JavaScriptCore/pcre/pcre_exec.cpp
@@ -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;
- if (isprint(c = *(p++)))
+ if (isASCIIPrintable(c = *(p++)))
printf("%c", c);
else if (c < 256)
printf("\\x%02x", c);
diff --git a/JavaScriptCore/profiler/CallIdentifier.h b/JavaScriptCore/profiler/CallIdentifier.h
index ba48c55..f2d04fc 100644
--- a/JavaScriptCore/profiler/CallIdentifier.h
+++ b/JavaScriptCore/profiler/CallIdentifier.h
@@ -44,7 +44,7 @@ namespace JSC {
CallIdentifier(const UString& name, const UString& url, int lineNumber)
: m_name(name)
- , m_url(url)
+ , m_url(!url.isNull() ? url : "")
, m_lineNumber(lineNumber)
{
}
@@ -71,7 +71,7 @@ namespace JSC {
#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
};
diff --git a/JavaScriptCore/profiler/Profile.cpp b/JavaScriptCore/profiler/Profile.cpp
index c90f9b0..126e6f6 100644
--- a/JavaScriptCore/profiler/Profile.cpp
+++ b/JavaScriptCore/profiler/Profile.cpp
@@ -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)
- 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");
}
diff --git a/JavaScriptCore/profiler/ProfileGenerator.cpp b/JavaScriptCore/profiler/ProfileGenerator.cpp
index f367033..bdfa27b 100644
--- a/JavaScriptCore/profiler/ProfileGenerator.cpp
+++ b/JavaScriptCore/profiler/ProfileGenerator.cpp
@@ -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();
- 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)
@@ -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();
- 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)
diff --git a/JavaScriptCore/profiler/ProfileNode.cpp b/JavaScriptCore/profiler/ProfileNode.cpp
index fb126b3..f60c72e 100644
--- a/JavaScriptCore/profiler/ProfileNode.cpp
+++ b/JavaScriptCore/profiler/ProfileNode.cpp
@@ -32,6 +32,7 @@
#include "Profiler.h"
#include <stdio.h>
#include <wtf/DateMath.h>
+#include <wtf/text/StringHash.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",
- functionName().UTF8String().c_str(),
+ functionName().UTF8String().data(),
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;
@@ -312,7 +313,7 @@ double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashC
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)
@@ -338,7 +339,7 @@ double ProfileNode::debugPrintDataSampleStyle(int indentLevel, FunctionCallHashC
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;
diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro
index c87eaf4..88629c7 100644
--- a/JavaScriptCore/qt/api/QtScript.pro
+++ b/JavaScriptCore/qt/api/QtScript.pro
@@ -13,14 +13,20 @@ CONFIG(debug, debug|release) {
OBJECTS_DIR = obj/release
}
+isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../..
include($$PWD/../../../WebKit.pri)
+
include($$PWD/../../JavaScriptCore.pri)
+addJavaScriptCoreLib(../..)
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 \
@@ -28,9 +34,13 @@ HEADERS += $$PWD/qtscriptglobal.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
-
diff --git a/JavaScriptCore/qt/api/qscriptconverter_p.h b/JavaScriptCore/qt/api/qscriptconverter_p.h
index c3ca41f..cd86e20 100644
--- a/JavaScriptCore/qt/api/qscriptconverter_p.h
+++ b/JavaScriptCore/qt/api/qscriptconverter_p.h
@@ -21,7 +21,11 @@
#define qscriptconverter_p_h
#include <JavaScriptCore/JavaScript.h>
+#include <QtCore/qnumeric.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
@@ -33,6 +37,19 @@
*/
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));
@@ -45,6 +62,71 @@ public:
{
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
diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp
index fbeb902..d49c578 100644
--- a/JavaScriptCore/qt/api/qscriptengine.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine.cpp
@@ -22,6 +22,8 @@
#include "qscriptengine.h"
#include "qscriptengine_p.h"
+#include "qscriptprogram_p.h"
+#include "qscriptsyntaxcheckresult_p.h"
#include "qscriptvalue_p.h"
/*!
@@ -42,6 +44,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.
@@ -71,6 +90,11 @@ QScriptValue QScriptEngine::evaluate(const QString& program, const QString& file
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.
@@ -81,6 +105,8 @@ 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.
+
+ \sa reportAdditionalMemoryCost()
*/
void QScriptEngine::collectGarbage()
{
@@ -88,6 +114,43 @@ void QScriptEngine::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()
@@ -106,3 +169,18 @@ 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());
+}
diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h
index b8bd5e6..e10888d 100644
--- a/JavaScriptCore/qt/api/qscriptengine.h
+++ b/JavaScriptCore/qt/api/qscriptengine.h
@@ -20,6 +20,9 @@
#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>
@@ -35,11 +38,18 @@ public:
QScriptEngine();
~QScriptEngine();
+ static QScriptSyntaxCheckResult checkSyntax(const QString& program);
QScriptValue evaluate(const QString& program, const QString& fileName = QString(), int lineNumber = 1);
+ QScriptValue evaluate(const QScriptProgram& program);
+
void collectGarbage();
+ void reportAdditionalMemoryCost(int cost);
+
+ QScriptString toStringHandle(const QString& str);
QScriptValue nullValue();
QScriptValue undefinedValue();
+ QScriptValue globalObject() const;
private:
friend class QScriptEnginePrivate;
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp
index de8a355..38185ab 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp
@@ -21,6 +21,7 @@
#include "qscriptengine_p.h"
+#include "qscriptprogram_p.h"
#include "qscriptvalue_p.h"
/*!
@@ -38,6 +39,19 @@ QScriptEnginePrivate::~QScriptEnginePrivate()
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
@@ -46,9 +60,25 @@ QScriptValuePrivate* QScriptEnginePrivate::evaluate(const QString& program, cons
{
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);
}
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h
index 8e27c42..2bda68e 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.h
+++ b/JavaScriptCore/qt/api/qscriptengine_p.h
@@ -22,12 +22,16 @@
#include "qscriptconverter_p.h"
#include "qscriptengine.h"
+#include "qscriptstring_p.h"
+#include "qscriptsyntaxcheckresult_p.h"
#include "qscriptvalue.h"
#include <JavaScriptCore/JavaScript.h>
+#include <JSBasePrivate.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qstring.h>
class QScriptEngine;
+class QScriptSyntaxCheckResultPrivate;
class QScriptEnginePrivate : public QSharedData {
public:
@@ -37,8 +41,13 @@ public:
QScriptEnginePrivate(const QScriptEngine*);
~QScriptEnginePrivate();
+ QScriptSyntaxCheckResultPrivate* checkSyntax(const QString& program);
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 reportAdditionalMemoryCost(int cost);
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;
+ QScriptValuePrivate* globalObject() const;
+
+ inline QScriptStringPrivate* toStringHandle(const QString& str) const;
+
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::reportAdditionalMemoryCost(int cost)
+{
+ if (cost > 0)
+ JSReportExtraMemoryCost(m_context, cost);
+}
+
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
{
- 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
@@ -90,6 +127,11 @@ JSValueRef QScriptEnginePrivate::makeJSValue(QScriptValue::SpecialValue value) c
return JSValueMakeUndefined(m_context);
}
+QScriptStringPrivate* QScriptEnginePrivate::toStringHandle(const QString& str) const
+{
+ return new QScriptStringPrivate(str);
+}
+
JSGlobalContextRef QScriptEnginePrivate::context() const
{
return m_context;
diff --git a/JavaScriptCore/qt/api/qscriptprogram.cpp b/JavaScriptCore/qt/api/qscriptprogram.cpp
new file mode 100644
index 0000000..d7d4948
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptprogram.cpp
@@ -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/JavaScriptCore/qt/api/qscriptprogram.h b/JavaScriptCore/qt/api/qscriptprogram.h
new file mode 100644
index 0000000..93c8a3c
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptprogram.h
@@ -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/JavaScriptCore/qt/api/qscriptprogram_p.h b/JavaScriptCore/qt/api/qscriptprogram_p.h
new file mode 100644
index 0000000..6e80e85
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptprogram_p.h
@@ -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/JavaScriptCore/qt/api/qscriptstring.cpp b/JavaScriptCore/qt/api/qscriptstring.cpp
new file mode 100644
index 0000000..83c03c5
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptstring.cpp
@@ -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/JavaScriptCore/qt/api/qscriptstring.h b/JavaScriptCore/qt/api/qscriptstring.h
new file mode 100644
index 0000000..16593bc
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptstring.h
@@ -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/JavaScriptCore/qt/api/qscriptstring_p.h b/JavaScriptCore/qt/api/qscriptstring_p.h
new file mode 100644
index 0000000..f4fd117
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptstring_p.h
@@ -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(JSStringRetain(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/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp b/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp
new file mode 100644
index 0000000..5cf02ef
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.cpp
@@ -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/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h b/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h
new file mode 100644
index 0000000..aa57744
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptsyntaxcheckresult.h
@@ -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/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h b/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h
new file mode 100644
index 0000000..6e1a131
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptsyntaxcheckresult_p.h
@@ -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
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
index 8db43a7..830b38e 100644
--- a/JavaScriptCore/qt/api/qscriptvalue_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -38,10 +38,10 @@ class QScriptValue;
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.
- 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,
@@ -53,7 +53,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.
- 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
@@ -117,14 +117,14 @@ public:
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.
- JSNative,
+ JSPrimitive,
JSObject
} m_state;
QScriptEnginePtr m_engine;
@@ -136,6 +136,7 @@ private:
inline void setValue(JSValueRef);
inline bool inherits(const char*);
+ inline State refinedJSValue();
inline bool isJSBased() const;
inline bool isNumberBased() const;
@@ -209,7 +210,7 @@ QScriptValuePrivate::QScriptValuePrivate(QScriptValue::SpecialValue value)
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, bool value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -224,7 +225,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, bool value
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, int value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -239,7 +240,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, int value)
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, uint value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -254,7 +255,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, uint value
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, qsreal value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -269,7 +270,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, qsreal val
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, const QString& value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -284,7 +285,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, const QStr
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, QScriptValue::SpecialValue value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -325,10 +326,10 @@ bool QScriptValuePrivate::isBool()
case CBool:
return true;
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsBoolean(context(), value());
default:
return false;
@@ -341,10 +342,10 @@ bool QScriptValuePrivate::isNumber()
case CNumber:
return true;
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsNumber(context(), value());
default:
return false;
@@ -357,10 +358,10 @@ bool QScriptValuePrivate::isNull()
case CSpecial:
return m_number == static_cast<int>(QScriptValue::NullValue);
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsNull(context(), value());
default:
return false;
@@ -373,10 +374,10 @@ bool QScriptValuePrivate::isString()
case CString:
return true;
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsString(context(), value());
default:
return false;
@@ -389,10 +390,10 @@ bool QScriptValuePrivate::isUndefined()
case CSpecial:
return m_number == static_cast<int>(QScriptValue::UndefinedValue);
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsUndefined(context(), value());
default:
return false;
@@ -403,7 +404,7 @@ bool QScriptValuePrivate::isError()
{
switch (m_state) {
case JSValue:
- if (!isObject())
+ if (refinedJSValue() != JSObject)
return false;
// Fall-through.
case JSObject:
@@ -416,14 +417,11 @@ bool QScriptValuePrivate::isError()
bool QScriptValuePrivate::isObject()
{
switch (m_state) {
- case JSObject:
- return true;
case JSValue:
- m_object = JSValueToObject(context(), value(), /* exception */ 0);
- if (!m_object)
- return false;
- m_state = JSObject;
+ return refinedJSValue() == JSObject;
+ case JSObject:
return true;
+
default:
return false;
}
@@ -433,10 +431,8 @@ bool QScriptValuePrivate::isFunction()
{
switch (m_state) {
case JSValue:
- m_object = JSValueToObject(context(), value(), /* exception */ 0);
- if (!m_object)
+ if (refinedJSValue() != JSObject)
return false;
- m_state = JSObject;
// Fall-through.
case JSObject:
return JSObjectIsFunction(context(), object());
@@ -455,11 +451,11 @@ QString QScriptValuePrivate::toString() const
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 JSNative:
+ case JSPrimitive:
case JSObject:
return QScriptConverter::toString(JSValueToStringCopy(context(), value(), /* exception */ 0));
}
@@ -472,7 +468,7 @@ qsreal QScriptValuePrivate::toNumber() const
{
switch (m_state) {
case JSValue:
- case JSNative:
+ case JSPrimitive:
case JSObject:
return JSValueToNumber(context(), value(), /* exception */ 0);
case CNumber:
@@ -504,7 +500,7 @@ bool QScriptValuePrivate::toBool() const
{
switch (m_state) {
case JSValue:
- case JSNative:
+ case JSPrimitive:
return JSValueToBoolean(context(), value());
case JSObject:
return true;
@@ -631,7 +627,7 @@ bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine)
return false;
}
m_engine = engine;
- m_state = JSNative;
+ m_state = JSPrimitive;
setValue(value);
return true;
}
@@ -640,12 +636,8 @@ QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const
{
switch (m_state) {
case JSValue:
- m_object = JSValueToObject(context(), value(), /* exception */ 0);
- if (!object()) {
- m_state = JSValue;
+ if (refinedJSValue() != JSObject)
return new QScriptValuePrivate;
- }
- m_state = JSObject;
// Fall-through.
case JSObject:
{
@@ -719,12 +711,32 @@ bool QScriptValuePrivate::inherits(const char* name)
{
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);
}
/*!
\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.
*/
bool QScriptValuePrivate::isJSBased() const { return m_state >= JSValue; }
diff --git a/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro b/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro
index 0dc0902..d521dd8 100644
--- a/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro
+++ b/JavaScriptCore/qt/tests/qscriptengine/qscriptengine.pro
@@ -1,6 +1,7 @@
TEMPLATE = app
TARGET = tst_qscriptengine
QT += testlib
+isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../..
include(../tests.pri)
SOURCES += tst_qscriptengine.cpp
diff --git a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
index b36e364..1ec9ad3 100644
--- a/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
+++ b/JavaScriptCore/qt/tests/qscriptengine/tst_qscriptengine.cpp
@@ -18,6 +18,8 @@
*/
#include "qscriptengine.h"
+#include "qscriptprogram.h"
+#include "qscriptsyntaxcheckresult.h"
#include "qscriptvalue.h"
#include <QtTest/qtest.h>
@@ -33,10 +35,15 @@ public slots:
void cleanup() {}
private slots:
+ void globalObject();
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. */
@@ -47,6 +54,17 @@ void tst_QScriptEngine::evaluate()
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()
{
@@ -57,6 +75,26 @@ void tst_QScriptEngine::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;
@@ -73,5 +111,198 @@ void tst_QScriptEngine::undefinedValue()
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"
diff --git a/JavaScriptCore/qt/tests/qscriptstring/qscriptstring.pro b/JavaScriptCore/qt/tests/qscriptstring/qscriptstring.pro
new file mode 100644
index 0000000..5ad9b7c
--- /dev/null
+++ b/JavaScriptCore/qt/tests/qscriptstring/qscriptstring.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = tst_qscriptstring
+QT += testlib
+include(../tests.pri)
+
+SOURCES += tst_qscriptstring.cpp
+
diff --git a/JavaScriptCore/qt/tests/qscriptstring/tst_qscriptstring.cpp b/JavaScriptCore/qt/tests/qscriptstring/tst_qscriptstring.cpp
new file mode 100644
index 0000000..ff31835
--- /dev/null
+++ b/JavaScriptCore/qt/tests/qscriptstring/tst_qscriptstring.cpp
@@ -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
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro b/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro
index b12337f..35cc17d 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro
+++ b/JavaScriptCore/qt/tests/qscriptvalue/qscriptvalue.pro
@@ -1,6 +1,7 @@
TEMPLATE = app
TARGET = tst_qscriptvalue
QT += testlib
+isEmpty(OUTPUT_DIR): OUTPUT_DIR = ../../../..
include(../tests.pri)
SOURCES += \
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
index b44c5ca..82f0901 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
@@ -274,7 +274,7 @@ void tst_QScriptValue::ctor()
QVERIFY(QScriptValue(0, QString("ciao")).isString());
}
-void tst_QScriptValue::toString_data()
+void tst_QScriptValue::toStringSimple_data()
{
QTest::addColumn<QString>("code");
QTest::addColumn<QString>("result");
@@ -289,7 +289,7 @@ void tst_QScriptValue::toString_data()
}
/* Test conversion to string from different JSC types */
-void tst_QScriptValue::toString()
+void tst_QScriptValue::toStringSimple()
{
QFETCH(QString, code);
QFETCH(QString, result);
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
index 1b3c657..28154a9 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
@@ -36,8 +36,8 @@ public:
virtual ~tst_QScriptValue();
private slots:
- void toString_data();
- void toString();
+ void toStringSimple_data();
+ void toStringSimple();
void copyConstructor_data();
void copyConstructor();
void assignOperator_data();
@@ -76,6 +76,9 @@ private slots:
void isValid_data();
void isValid();
+ void toString_data();
+ void toString();
+
void toNumber_data();
void toNumber();
@@ -146,6 +149,10 @@ private:
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&);
diff --git a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp
index 006b343..970c960 100644
--- a/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp
+++ b/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue_generated.cpp
@@ -130,6 +130,35 @@ void tst_QScriptValue::initScriptValues()
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());
}
@@ -244,7 +273,36 @@ void tst_QScriptValue::isValid_makeData(const char* expr)
<< "engine->evaluate(\"/foo/\")"
<< "engine->evaluate(\"new Object()\")"
<< "engine->evaluate(\"new Array()\")"
- << "engine->evaluate(\"new Error()\")";
+ << "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);
}
@@ -253,6 +311,7 @@ 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)
@@ -273,7 +332,9 @@ void tst_QScriptValue::isBool_makeData(const char* expr)
<< "QScriptValue(0, true)"
<< "QScriptValue(0, false)"
<< "QScriptValue(engine, true)"
- << "QScriptValue(engine, false)";
+ << "QScriptValue(engine, false)"
+ << "engine->evaluate(\"true\")"
+ << "engine->evaluate(\"false\")";
}
newRow(expr) << isBool.contains(expr);
}
@@ -282,6 +343,7 @@ 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)
@@ -302,7 +364,9 @@ void tst_QScriptValue::isBoolean_makeData(const char* expr)
<< "QScriptValue(0, true)"
<< "QScriptValue(0, false)"
<< "QScriptValue(engine, true)"
- << "QScriptValue(engine, false)";
+ << "QScriptValue(engine, false)"
+ << "engine->evaluate(\"true\")"
+ << "engine->evaluate(\"false\")";
}
newRow(expr) << isBoolean.contains(expr);
}
@@ -311,10 +375,12 @@ 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");
@@ -366,7 +432,21 @@ void tst_QScriptValue::isNumber_makeData(const char* expr)
<< "QScriptValue(engine, qSNaN())"
<< "QScriptValue(engine, qQNaN())"
<< "QScriptValue(engine, qInf())"
- << "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);
}
@@ -375,6 +455,7 @@ 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)
@@ -407,6 +488,7 @@ 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)
@@ -424,7 +506,9 @@ void tst_QScriptValue::isNull_makeData(const char* expr)
if (isNull.isEmpty()) {
isNull << "QScriptValue(QScriptValue::NullValue)"
<< "QScriptValue(0, QScriptValue::NullValue)"
- << "QScriptValue(engine, QScriptValue::NullValue)";
+ << "QScriptValue(engine, QScriptValue::NullValue)"
+ << "engine->evaluate(\"null\")"
+ << "engine->nullValue()";
}
newRow(expr) << isNull.contains(expr);
}
@@ -433,6 +517,7 @@ 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)
@@ -477,7 +562,12 @@ void tst_QScriptValue::isString_makeData(const char* expr)
<< "QScriptValue(engine, QString())"
<< "QScriptValue(engine, QString(\"0\"))"
<< "QScriptValue(engine, QString(\"123\"))"
- << "QScriptValue(engine, QString(\"1.23\"))";
+ << "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);
}
@@ -486,6 +576,7 @@ 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)
@@ -504,7 +595,9 @@ void tst_QScriptValue::isUndefined_makeData(const char* expr)
isUndefined << "QScriptValue(QScriptValue::UndefinedValue)"
<< "QScriptValue(0, QScriptValue::UndefinedValue)"
<< "QScriptValue(engine, QScriptValue::UndefinedValue)"
- << "engine->evaluate(\"{}\")";
+ << "engine->evaluate(\"{}\")"
+ << "engine->evaluate(\"undefined\")"
+ << "engine->undefinedValue()";
}
newRow(expr) << isUndefined.contains(expr);
}
@@ -513,10 +606,15 @@ 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");
@@ -543,7 +641,11 @@ void tst_QScriptValue::isObject_makeData(const char* expr)
<< "engine->evaluate(\"/foo/\")"
<< "engine->evaluate(\"new Object()\")"
<< "engine->evaluate(\"new Array()\")"
- << "engine->evaluate(\"new Error()\")";
+ << "engine->evaluate(\"new Error()\")"
+ << "engine->evaluate(\"Undefined\")"
+ << "engine->evaluate(\"Null\")"
+ << "engine->evaluate(\"True\")"
+ << "engine->evaluate(\"False\")";
}
newRow(expr) << isObject.contains(expr);
}
@@ -552,10 +654,168 @@ 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");
@@ -669,6 +929,35 @@ void tst_QScriptValue::toNumber_makeData(const char* expr)
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);
}
@@ -682,9 +971,11 @@ void tst_QScriptValue::toNumber_test(const char*, const QScriptValue& value)
}
if (qIsInf(expected)) {
QVERIFY(qIsInf(value.toNumber()));
+ QVERIFY(qIsInf(value.toNumber()));
return;
}
QCOMPARE(value.toNumber(), expected);
+ QCOMPARE(value.toNumber(), expected);
}
DEFINE_TEST_FUNCTION(toNumber)
@@ -803,6 +1094,35 @@ void tst_QScriptValue::toBool_makeData(const char* expr)
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);
}
@@ -811,6 +1131,7 @@ 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)
@@ -929,6 +1250,35 @@ void tst_QScriptValue::toBoolean_makeData(const char* expr)
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);
}
@@ -937,6 +1287,7 @@ 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)
@@ -1055,6 +1406,35 @@ void tst_QScriptValue::toInteger_makeData(const char* expr)
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);
}
@@ -1064,9 +1444,11 @@ 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)
@@ -1185,6 +1567,35 @@ void tst_QScriptValue::toInt32_makeData(const char* expr)
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);
}
@@ -1193,6 +1604,7 @@ 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)
@@ -1311,6 +1723,35 @@ void tst_QScriptValue::toUInt32_makeData(const char* expr)
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);
}
@@ -1319,6 +1760,7 @@ 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)
@@ -1437,6 +1879,35 @@ void tst_QScriptValue::toUInt16_makeData(const char* expr)
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);
}
@@ -1445,6 +1916,7 @@ 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)
diff --git a/JavaScriptCore/qt/tests/tests.pri b/JavaScriptCore/qt/tests/tests.pri
index 1ce238f..5af3383 100644
--- a/JavaScriptCore/qt/tests/tests.pri
+++ b/JavaScriptCore/qt/tests/tests.pri
@@ -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) {
diff --git a/JavaScriptCore/qt/tests/tests.pro b/JavaScriptCore/qt/tests/tests.pro
index 6e5edb1..7c3f590 100644
--- a/JavaScriptCore/qt/tests/tests.pro
+++ b/JavaScriptCore/qt/tests/tests.pro
@@ -1,3 +1,4 @@
TEMPLATE = subdirs
SUBDIRS = qscriptengine \
- qscriptvalue
+ qscriptvalue \
+ qscriptstring
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index 6d79581..bd14e64 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -24,13 +24,13 @@
#include "config.h"
#include "ArrayPrototype.h"
-#include "CodeBlock.h"
#include "CachedCall.h"
+#include "CodeBlock.h"
#include "Interpreter.h"
#include "JIT.h"
#include "JSStringBuilder.h"
-#include "ObjectPrototype.h"
#include "Lookup.h"
+#include "ObjectPrototype.h"
#include "Operations.h"
#include <algorithm>
#include <wtf/Assertions.h>
@@ -156,9 +156,9 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
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;
@@ -201,7 +201,7 @@ JSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec, JSObject*, JSValue
if (i)
buffer.append(',');
if (RefPtr<UString::Rep> rep = strBuffer[i])
- buffer.append(rep->data(), rep->length());
+ buffer.append(rep->characters(), rep->length());
}
ASSERT(buffer.size() == totalSize);
return jsString(exec, UString::adopt(buffer));
@@ -214,9 +214,9 @@ JSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec, JSObject*, J
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;
@@ -252,9 +252,9 @@ JSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec, JSObject*, JSValue thi
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;
@@ -506,14 +506,19 @@ JSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec, JSObject*, JSValue t
// 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();
- 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)
@@ -539,7 +544,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 - 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
diff --git a/JavaScriptCore/runtime/Collector.cpp b/JavaScriptCore/runtime/Collector.cpp
index 2873e0b..9b72755 100644
--- a/JavaScriptCore/runtime/Collector.cpp
+++ b/JavaScriptCore/runtime/Collector.cpp
@@ -53,11 +53,6 @@
#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>
@@ -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))
-#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)
@@ -145,30 +135,12 @@ Heap::Heap(JSGlobalData* globalData)
, m_registeredThreads(0)
, m_currentThreadRegistrar(0)
#endif
+#if OS(SYMBIAN)
+ , m_blockallocator(JSCCOLLECTOR_VIRTUALMEM_RESERVATION, BLOCK_SIZE)
+#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();
}
@@ -211,7 +183,9 @@ void Heap::destroy()
t = next;
}
#endif
-
+#if OS(SYMBIAN)
+ m_blockallocator.destroy();
+#endif
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)
- // 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();
- 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)
-#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);
@@ -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)
- userChunk->Free(reinterpret_cast<TAny*>(block));
+ m_blockallocator.free(reinterpret_cast<void*>(block));
#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);
@@ -574,10 +546,6 @@ static inline void* currentThreadStackBase()
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
@@ -586,6 +554,9 @@ static inline void* currentThreadStackBase()
: "=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)
return currentThreadStackBaseQNX();
#elif OS(SOLARIS)
@@ -667,7 +638,7 @@ void Heap::makeUsableFromMultipleThreads()
void Heap::registerThread()
{
- ASSERT(!m_globalData->mainThreadOnly || isMainThread());
+ ASSERT(!m_globalData->exclusiveThread || m_globalData->exclusiveThread == currentThread());
if (!m_currentThreadRegistrar || pthread_getspecific(m_currentThreadRegistrar))
return;
@@ -1009,15 +980,15 @@ void Heap::protect(JSValue k)
m_protectedValues.add(k.asCell());
}
-void Heap::unprotect(JSValue k)
+bool Heap::unprotect(JSValue k)
{
ASSERT(k);
ASSERT(JSLock::currentThreadIsHoldingLock() || !m_globalData->isSharedInstance);
if (!k.isCell())
- return;
+ return false;
- m_protectedValues.remove(k.asCell());
+ return m_protectedValues.remove(k.asCell());
}
void Heap::markProtectedObjects(MarkStack& markStack)
diff --git a/JavaScriptCore/runtime/Collector.h b/JavaScriptCore/runtime/Collector.h
index 82aa8a1..3db3d7e 100644
--- a/JavaScriptCore/runtime/Collector.h
+++ b/JavaScriptCore/runtime/Collector.h
@@ -35,6 +35,10 @@
#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 {
@@ -91,7 +95,9 @@ namespace JSC {
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*);
@@ -168,6 +174,11 @@ namespace JSC {
pthread_key_t m_currentThreadRegistrar;
#endif
+#if OS(SYMBIAN)
+ // Allocates collector blocks with correct alignment
+ WTF::AlignedBlockAllocator m_blockallocator;
+#endif
+
JSGlobalData* m_globalData;
};
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.cpp b/JavaScriptCore/runtime/CommonIdentifiers.cpp
index ed5e304..3837817 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.cpp
+++ b/JavaScriptCore/runtime/CommonIdentifiers.cpp
@@ -28,7 +28,8 @@ static const char* const nullCString = 0;
#define INITIALIZE_PROPERTY_NAME(name) , name(globalData, #name)
CommonIdentifiers::CommonIdentifiers(JSGlobalData* globalData)
- : emptyIdentifier(globalData, "")
+ : nullIdentifier(globalData, nullCString)
+ , emptyIdentifier(globalData, "")
, underscoreProto(globalData, "__proto__")
, thisIdentifier(globalData, "this")
JSC_COMMON_IDENTIFIERS_EACH_PROPERTY_NAME(INITIALIZE_PROPERTY_NAME)
diff --git a/JavaScriptCore/runtime/CommonIdentifiers.h b/JavaScriptCore/runtime/CommonIdentifiers.h
index 0a3d774..de24f4a 100644
--- a/JavaScriptCore/runtime/CommonIdentifiers.h
+++ b/JavaScriptCore/runtime/CommonIdentifiers.h
@@ -90,6 +90,7 @@ namespace JSC {
friend class JSGlobalData;
public:
+ const Identifier nullIdentifier;
const Identifier emptyIdentifier;
const Identifier underscoreProto;
const Identifier thisIdentifier;
diff --git a/JavaScriptCore/runtime/Completion.cpp b/JavaScriptCore/runtime/Completion.cpp
index 2f88df9..9af5171 100644
--- a/JavaScriptCore/runtime/Completion.cpp
+++ b/JavaScriptCore/runtime/Completion.cpp
@@ -29,6 +29,7 @@
#include "Interpreter.h"
#include "Parser.h"
#include "Debugger.h"
+#include "WTFThreadData.h"
#include <stdio.h>
namespace JSC {
@@ -36,7 +37,7 @@ namespace JSC {
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);
@@ -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);
- 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());
@@ -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) {
- 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);
}
diff --git a/JavaScriptCore/runtime/Completion.h b/JavaScriptCore/runtime/Completion.h
index 41c9a64..63b315e 100644
--- a/JavaScriptCore/runtime/Completion.h
+++ b/JavaScriptCore/runtime/Completion.h
@@ -31,7 +31,7 @@ namespace JSC {
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
diff --git a/JavaScriptCore/runtime/DateConversion.cpp b/JavaScriptCore/runtime/DateConversion.cpp
index f129407..70dbaa0 100644
--- a/JavaScriptCore/runtime/DateConversion.cpp
+++ b/JavaScriptCore/runtime/DateConversion.cpp
@@ -56,7 +56,7 @@ double parseDate(ExecState* exec, const UString &date)
{
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;
diff --git a/JavaScriptCore/runtime/DatePrototype.cpp b/JavaScriptCore/runtime/DatePrototype.cpp
index 25b0ac4..d331409 100644
--- a/JavaScriptCore/runtime/DatePrototype.cpp
+++ b/JavaScriptCore/runtime/DatePrototype.cpp
@@ -24,11 +24,12 @@
#include "DatePrototype.h"
#include "DateConversion.h"
+#include "DateInstance.h"
#include "Error.h"
#include "JSString.h"
#include "JSStringBuilder.h"
+#include "Lookup.h"
#include "ObjectPrototype.h"
-#include "DateInstance.h"
#if !PLATFORM(MAC) && HAVE(LANGINFO_H)
#include <langinfo.h>
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.cpp b/JavaScriptCore/runtime/ExceptionHelpers.cpp
index b9c6319..aee6f31 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.cpp
+++ b/JavaScriptCore/runtime/ExceptionHelpers.cpp
@@ -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."; }
};
@@ -56,6 +56,23 @@ JSValue createInterruptedExecutionException(JSGlobalData* 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)
{
return Error::create(exec, e, msg, -1, -1, UString());
diff --git a/JavaScriptCore/runtime/ExceptionHelpers.h b/JavaScriptCore/runtime/ExceptionHelpers.h
index b6e7373..b152439 100644
--- a/JavaScriptCore/runtime/ExceptionHelpers.h
+++ b/JavaScriptCore/runtime/ExceptionHelpers.h
@@ -43,6 +43,7 @@ namespace JSC {
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*);
diff --git a/JavaScriptCore/runtime/FunctionPrototype.cpp b/JavaScriptCore/runtime/FunctionPrototype.cpp
index 3475f08..a77b5b2 100644
--- a/JavaScriptCore/runtime/FunctionPrototype.cpp
+++ b/JavaScriptCore/runtime/FunctionPrototype.cpp
@@ -39,7 +39,7 @@ static JSValue JSC_HOST_CALL functionProtoFuncApply(ExecState*, JSObject*, JSVal
static JSValue JSC_HOST_CALL functionProtoFuncCall(ExecState*, JSObject*, JSValue, const ArgList&);
FunctionPrototype::FunctionPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure)
- : InternalFunction(&exec->globalData(), structure, exec->propertyNames().emptyIdentifier)
+ : InternalFunction(&exec->globalData(), structure, exec->propertyNames().nullIdentifier)
{
putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 0), DontDelete | ReadOnly | DontEnum);
}
diff --git a/JavaScriptCore/runtime/GetterSetter.h b/JavaScriptCore/runtime/GetterSetter.h
index 4e47361..27ffbe7 100644
--- a/JavaScriptCore/runtime/GetterSetter.h
+++ b/JavaScriptCore/runtime/GetterSetter.h
@@ -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 {
+ friend class JIT;
public:
GetterSetter(ExecState* exec)
: JSCell(exec->globalData().getterSetterStructure.get())
diff --git a/JavaScriptCore/runtime/Identifier.cpp b/JavaScriptCore/runtime/Identifier.cpp
index 46fcd0b..f2642a9 100644
--- a/JavaScriptCore/runtime/Identifier.cpp
+++ b/JavaScriptCore/runtime/Identifier.cpp
@@ -22,50 +22,38 @@
#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 <wtf/WTFThreadData.h>
+#include <wtf/text/StringHash.h>
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()
{
@@ -80,7 +68,7 @@ void deleteIdentifierTable(IdentifierTable* table)
bool Identifier::equal(const UString::Rep* r, const char* s)
{
int length = r->length();
- const UChar* d = r->data();
+ const UChar* d = r->characters();
for (int i = 0; i != length; ++i)
if (d[i] != (unsigned char)s[i])
return false;
@@ -91,14 +79,14 @@ bool Identifier::equal(const UString::Rep* r, const UChar* s, unsigned length)
{
if (r->length() != length)
return false;
- const UChar* d = r->data();
+ const UChar* d = r->characters();
for (unsigned i = 0; i != length; ++i)
if (d[i] != s[i])
return false;
return true;
}
-struct CStringTranslator {
+struct IdentifierCStringTranslator {
static unsigned hash(const char* c)
{
return UString::Rep::computeHash(c);
@@ -123,12 +111,10 @@ struct CStringTranslator {
PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c)
{
- ASSERT(c);
-
- 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])));
@@ -139,7 +125,7 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const char* c
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.
@@ -160,7 +146,7 @@ struct UCharBuffer {
unsigned int length;
};
-struct UCharBufferTranslator {
+struct IdentifierUCharBufferTranslator {
static unsigned hash(const UCharBuffer& buf)
{
return UString::Rep::computeHash(buf.s, buf.length);
@@ -189,12 +175,10 @@ PassRefPtr<UString::Rep> Identifier::add(JSGlobalData* globalData, const UChar*
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};
- 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.
@@ -209,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());
+ // 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->data()[0];
+ UChar c = r->characters()[0];
if (c <= 0xFF)
r = globalData->smallStrings.singleCharacterStringRep(c);
- if (r->isIdentifier()) {
-#ifndef NDEBUG
- checkSameIdentifierTable(globalData, r);
-#endif
+ if (r->isIdentifier())
return r;
- }
- }
- if (!r->length()) {
- UString::Rep::empty().hash();
- return &UString::Rep::empty();
}
+
return *globalData->identifierTable->add(r).first;
}
@@ -232,58 +213,41 @@ PassRefPtr<UString::Rep> Identifier::addSlowCase(ExecState* exec, UString::Rep*
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;
-
-#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>();
-}
-void createIdentifierTableSpecific()
-{
- pthread_once(&createIdentifierTableSpecificOnce, createIdentifierTableSpecificCallback);
- ASSERT(g_identifierTableSpecific);
+ checkCurrentIdentifierTable(&exec->globalData());
}
-#else
+#else
-void createIdentifierTableSpecific()
-{
- ASSERT(!g_identifierTableSpecific);
- g_identifierTableSpecific = new ThreadSpecific<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
diff --git a/JavaScriptCore/runtime/Identifier.h b/JavaScriptCore/runtime/Identifier.h
index 73e2af8..2f16bbf 100644
--- a/JavaScriptCore/runtime/Identifier.h
+++ b/JavaScriptCore/runtime/Identifier.h
@@ -54,9 +54,9 @@ namespace JSC {
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(); }
@@ -73,11 +73,9 @@ namespace JSC {
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 UChar*, unsigned length);
- static bool equal(const UString::Rep* a, const UString::Rep* b) { return JSC::equal(a, b); }
+ 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.
@@ -93,30 +91,28 @@ namespace JSC {
static PassRefPtr<UString::Rep> add(ExecState* exec, UString::Rep* r)
{
- if (r->isIdentifier()) {
#ifndef NDEBUG
- checkSameIdentifierTable(exec, r);
+ checkCurrentIdentifierTable(exec);
#endif
+ if (r->isIdentifier())
return r;
- }
return addSlowCase(exec, r);
}
static PassRefPtr<UString::Rep> add(JSGlobalData* globalData, UString::Rep* r)
{
- if (r->isIdentifier()) {
#ifndef NDEBUG
- checkSameIdentifierTable(globalData, r);
+ checkCurrentIdentifierTable(globalData);
#endif
+ if (r->isIdentifier())
return 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)
@@ -142,67 +138,6 @@ namespace JSC {
IdentifierTable* createIdentifierTable();
void deleteIdentifierTable(IdentifierTable*);
- struct ThreadIdentifierTableData {
- ThreadIdentifierTableData()
- : defaultIdentifierTable(0)
- , currentIdentifierTable(0)
- {
- }
-
- IdentifierTable* defaultIdentifierTable;
- IdentifierTable* currentIdentifierTable;
- };
-
- extern WTF::ThreadSpecific<ThreadIdentifierTableData>* g_identifierTableSpecific;
- void createIdentifierTableSpecific();
-
- inline IdentifierTable* defaultIdentifierTable()
- {
- if (!g_identifierTableSpecific)
- createIdentifierTableSpecific();
- ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
- return data.defaultIdentifierTable;
- }
-
- inline void setDefaultIdentifierTable(IdentifierTable* identifierTable)
- {
- if (!g_identifierTableSpecific)
- createIdentifierTableSpecific();
- ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
- data.defaultIdentifierTable = identifierTable;
- }
-
- inline IdentifierTable* currentIdentifierTable()
- {
- if (!g_identifierTableSpecific)
- createIdentifierTableSpecific();
- ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
- return data.currentIdentifierTable;
- }
-
- inline IdentifierTable* setCurrentIdentifierTable(IdentifierTable* identifierTable)
- {
- if (!g_identifierTableSpecific)
- createIdentifierTableSpecific();
- ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
- IdentifierTable* oldIdentifierTable = data.currentIdentifierTable;
- data.currentIdentifierTable = identifierTable;
- return oldIdentifierTable;
- }
-
- inline void resetCurrentIdentifierTable()
- {
- if (!g_identifierTableSpecific)
- createIdentifierTableSpecific();
- ThreadIdentifierTableData& data = **g_identifierTableSpecific;
-
- data.currentIdentifierTable = data.defaultIdentifierTable;
- }
-
} // namespace JSC
#endif // Identifier_h
diff --git a/JavaScriptCore/runtime/InitializeThreading.cpp b/JavaScriptCore/runtime/InitializeThreading.cpp
index 2605a9a..51d43ee 100644
--- a/JavaScriptCore/runtime/InitializeThreading.cpp
+++ b/JavaScriptCore/runtime/InitializeThreading.cpp
@@ -36,6 +36,7 @@
#include "UString.h"
#include <wtf/DateMath.h>
#include <wtf/Threading.h>
+#include <wtf/WTFThreadData.h>
using namespace WTF;
@@ -48,6 +49,7 @@ static pthread_once_t initializeThreadingKeyOnce = PTHREAD_ONCE_INIT;
static void initializeThreadingOnce()
{
WTF::initializeThreading();
+ wtfThreadData();
initializeUString();
JSGlobalData::storeVPtrs();
#if ENABLE(JSC_MULTIPLE_THREADS)
diff --git a/JavaScriptCore/runtime/InternalFunction.cpp b/JavaScriptCore/runtime/InternalFunction.cpp
index c48d628..717b5ff 100644
--- a/JavaScriptCore/runtime/InternalFunction.cpp
+++ b/JavaScriptCore/runtime/InternalFunction.cpp
@@ -40,7 +40,7 @@ const ClassInfo* InternalFunction::classInfo() const
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)
diff --git a/JavaScriptCore/runtime/JSAPIValueWrapper.h b/JavaScriptCore/runtime/JSAPIValueWrapper.h
index b5016c2..10ded4c 100644
--- a/JavaScriptCore/runtime/JSAPIValueWrapper.h
+++ b/JavaScriptCore/runtime/JSAPIValueWrapper.h
@@ -23,8 +23,6 @@
#ifndef JSAPIValueWrapper_h
#define JSAPIValueWrapper_h
-#include <wtf/Platform.h>
-
#include "JSCell.h"
#include "CallFrame.h"
diff --git a/JavaScriptCore/runtime/JSActivation.cpp b/JavaScriptCore/runtime/JSActivation.cpp
index 22fdaaf..85e8bba 100644
--- a/JavaScriptCore/runtime/JSActivation.cpp
+++ b/JavaScriptCore/runtime/JSActivation.cpp
@@ -139,9 +139,9 @@ bool JSActivation::isDynamicScope() const
return d()->functionExecutable->usesEval();
}
-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;
diff --git a/JavaScriptCore/runtime/JSActivation.h b/JavaScriptCore/runtime/JSActivation.h
index 761bee4..91c960c 100644
--- a/JavaScriptCore/runtime/JSActivation.h
+++ b/JavaScriptCore/runtime/JSActivation.h
@@ -89,7 +89,7 @@ namespace JSC {
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); }
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index 2be7371..d3ef44c 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -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_storage->lazyCreationData = 0;
+ m_storage->subclassData = 0;
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_storage->lazyCreationData = 0;
+ m_storage->subclassData = 0;
m_storage->reportedMapCapacity = 0;
size_t i = 0;
@@ -1022,14 +1022,14 @@ unsigned JSArray::compactForSorting()
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
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
index ad6ee88..f65f2bc 100644
--- a/JavaScriptCore/runtime/JSArray.h
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -31,7 +31,7 @@ namespace JSC {
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];
};
@@ -101,8 +101,8 @@ namespace JSC {
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; }
diff --git a/JavaScriptCore/runtime/JSCell.cpp b/JavaScriptCore/runtime/JSCell.cpp
index 869fbfc..0cc1ab1 100644
--- a/JavaScriptCore/runtime/JSCell.cpp
+++ b/JavaScriptCore/runtime/JSCell.cpp
@@ -163,16 +163,6 @@ JSObject* JSCell::toThisObject(ExecState* exec) const
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;
diff --git a/JavaScriptCore/runtime/JSCell.h b/JavaScriptCore/runtime/JSCell.h
index 3c8c829..772708f 100644
--- a/JavaScriptCore/runtime/JSCell.h
+++ b/JavaScriptCore/runtime/JSCell.h
@@ -107,8 +107,6 @@ namespace JSC {
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; }
@@ -301,11 +299,6 @@ namespace JSC {
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())
diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp
index d213b4a..cba6795 100644
--- a/JavaScriptCore/runtime/JSFunction.cpp
+++ b/JavaScriptCore/runtime/JSFunction.cpp
@@ -122,23 +122,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());
}
-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);
}
-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);
}
-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());
}
@@ -162,17 +162,17 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN
}
if (propertyName == exec->propertyNames().arguments) {
- slot.setCustom(this, argumentsGetter);
+ slot.setCacheableCustom(this, argumentsGetter);
return true;
}
if (propertyName == exec->propertyNames().length) {
- slot.setCustom(this, lengthGetter);
+ slot.setCacheableCustom(this, lengthGetter);
return true;
}
if (propertyName == exec->propertyNames().caller) {
- slot.setCustom(this, callerGetter);
+ slot.setCacheableCustom(this, callerGetter);
return true;
}
diff --git a/JavaScriptCore/runtime/JSFunction.h b/JavaScriptCore/runtime/JSFunction.h
index 8cd4b51..afa24a8 100644
--- a/JavaScriptCore/runtime/JSFunction.h
+++ b/JavaScriptCore/runtime/JSFunction.h
@@ -90,9 +90,9 @@ namespace JSC {
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()
diff --git a/JavaScriptCore/runtime/JSGlobalData.cpp b/JavaScriptCore/runtime/JSGlobalData.cpp
index 45abc86..2948d1c 100644
--- a/JavaScriptCore/runtime/JSGlobalData.cpp
+++ b/JavaScriptCore/runtime/JSGlobalData.cpp
@@ -49,6 +49,7 @@
#include "Lookup.h"
#include "Nodes.h"
#include "Parser.h"
+#include <wtf/WTFThreadData.h>
#if ENABLE(JSC_MULTIPLE_THREADS)
#include <wtf/Threading.h>
@@ -102,7 +103,7 @@ void JSGlobalData::storeVPtrs()
jsFunction->~JSCell();
}
-JSGlobalData::JSGlobalData(bool isShared)
+JSGlobalData::JSGlobalData(bool isShared, ThreadStackType threadStackType)
: isSharedInstance(isShared)
, clientData(0)
, arrayTable(fastNew<HashTable>(JSC::arrayTable))
@@ -115,6 +116,7 @@ JSGlobalData::JSGlobalData(bool isShared)
, 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()))
@@ -144,8 +146,9 @@ JSGlobalData::JSGlobalData(bool isShared)
, markStack(jsArrayVPtr)
, cachedUTCOffset(NaN)
, weakRandom(static_cast<int>(currentTime()))
+ , maxReentryDepth(threadStackType == ThreadStackTypeSmall ? MaxSmallThreadReentryDepth : MaxLargeThreadReentryDepth)
#ifndef NDEBUG
- , mainThreadOnly(false)
+ , exclusiveThread(0)
#endif
{
#if PLATFORM(MAC)
@@ -194,23 +197,22 @@ JSGlobalData::~JSGlobalData()
delete clientData;
}
-PassRefPtr<JSGlobalData> JSGlobalData::createNonDefault()
+PassRefPtr<JSGlobalData> JSGlobalData::createNonDefault(ThreadStackType type)
{
- return adoptRef(new JSGlobalData(false));
+ return adoptRef(new JSGlobalData(false, type));
}
-PassRefPtr<JSGlobalData> JSGlobalData::create()
+PassRefPtr<JSGlobalData> JSGlobalData::create(ThreadStackType type)
{
- JSGlobalData* globalData = new JSGlobalData(false);
- setDefaultIdentifierTable(globalData->identifierTable);
- setCurrentIdentifierTable(globalData->identifierTable);
+ JSGlobalData* globalData = new JSGlobalData(false, type);
+ wtfThreadData().initializeIdentifierTable(globalData->identifierTable);
return adoptRef(globalData);
}
-PassRefPtr<JSGlobalData> JSGlobalData::createLeaked()
+PassRefPtr<JSGlobalData> JSGlobalData::createLeaked(ThreadStackType type)
{
Structure::startIgnoringLeaks();
- RefPtr<JSGlobalData> data = create();
+ RefPtr<JSGlobalData> data = create(type);
Structure::stopIgnoringLeaks();
return data.release();
}
@@ -224,7 +226,7 @@ JSGlobalData& JSGlobalData::sharedInstance()
{
JSGlobalData*& instance = sharedInstanceInternal();
if (!instance) {
- instance = new JSGlobalData(true);
+ instance = new JSGlobalData(true, ThreadStackTypeSmall);
#if ENABLE(JSC_MULTIPLE_THREADS)
instance->makeUsableFromMultipleThreads();
#endif
diff --git a/JavaScriptCore/runtime/JSGlobalData.h b/JavaScriptCore/runtime/JSGlobalData.h
index 0f1f3c6..a90bf2c 100644
--- a/JavaScriptCore/runtime/JSGlobalData.h
+++ b/JavaScriptCore/runtime/JSGlobalData.h
@@ -37,6 +37,7 @@
#include "MarkStack.h"
#include "NumericStrings.h"
#include "SmallStrings.h"
+#include "Terminator.h"
#include "TimeoutChecker.h"
#include "WeakRandom.h"
#include <wtf/Forward.h>
@@ -83,6 +84,11 @@ namespace JSC {
double increment;
};
+ enum ThreadStackType {
+ ThreadStackTypeLarge,
+ ThreadStackTypeSmall
+ };
+
class JSGlobalData : public RefCounted<JSGlobalData> {
public:
struct ClientData {
@@ -92,9 +98,9 @@ namespace JSC {
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> createNonDefault(ThreadStackType);
~JSGlobalData();
#if ENABLE(JSC_MULTIPLE_THREADS)
@@ -116,6 +122,7 @@ namespace JSC {
RefPtr<Structure> activationStructure;
RefPtr<Structure> interruptedExecutionErrorStructure;
+ RefPtr<Structure> terminatedExecutionErrorStructure;
RefPtr<Structure> staticScopeStructure;
RefPtr<Structure> stringStructure;
RefPtr<Structure> notAnObjectErrorStubStructure;
@@ -153,6 +160,7 @@ namespace JSC {
JITThunks jitStubs;
#endif
TimeoutChecker timeoutChecker;
+ Terminator terminator;
Heap heap;
JSValue exception;
@@ -184,8 +192,9 @@ namespace JSC {
WeakRandom weakRandom;
+ int maxReentryDepth;
#ifndef NDEBUG
- bool mainThreadOnly;
+ ThreadIdentifier exclusiveThread;
#endif
void resetDateCache();
@@ -194,7 +203,7 @@ namespace JSC {
void stopSampling();
void dumpSampleData(ExecState* exec);
private:
- JSGlobalData(bool isShared);
+ JSGlobalData(bool isShared, ThreadStackType);
static JSGlobalData*& sharedInstanceInternal();
void createNativeThunk();
};
diff --git a/JavaScriptCore/runtime/JSGlobalObject.cpp b/JavaScriptCore/runtime/JSGlobalObject.cpp
index 4bf0a69..86690bd 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObject.cpp
@@ -319,9 +319,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),
- 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)
};
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index bbb6d5e..df942cf 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -25,6 +25,7 @@
#include "JSArray.h"
#include "JSGlobalData.h"
#include "JSVariableObject.h"
+#include "JSWeakObjectMapRefInternal.h"
#include "NativeFunctionWrapper.h"
#include "NumberPrototype.h"
#include "StringPrototype.h"
@@ -56,6 +57,7 @@ namespace JSC {
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
@@ -153,6 +155,7 @@ namespace JSC {
RefPtr<JSGlobalData> globalData;
HashSet<GlobalCodeBlock*> codeBlocks;
+ WeakMapSet weakMaps;
};
public:
@@ -270,6 +273,16 @@ namespace JSC {
return Structure::create(prototype, TypeInfo(ObjectType, StructureFlags), AnonymousSlotCount);
}
+ void registerWeakMap(OpaqueJSWeakObjectMap* map)
+ {
+ d()->weakMaps.add(map);
+ }
+
+ void deregisterWeakMap(OpaqueJSWeakObjectMap* map)
+ {
+ d()->weakMaps.remove(map);
+ }
+
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesMarkChildren | OverridesGetPropertyNames | JSVariableObject::StructureFlags;
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index 0e1fbee..5b6369a 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -35,6 +35,7 @@
#include "LiteralParser.h"
#include "Nodes.h"
#include "Parser.h"
+#include "StringBuilder.h"
#include "StringExtras.h"
#include "dtoa.h"
#include <stdio.h>
@@ -54,12 +55,12 @@ static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEsc
{
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.");
JSStringBuilder builder;
- const char* p = cstr.c_str();
- for (size_t k = 0; k < cstr.size(); k++, p++) {
+ 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);
@@ -429,8 +430,7 @@ JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, co
#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();
}
diff --git a/JavaScriptCore/runtime/JSImmediate.h b/JavaScriptCore/runtime/JSImmediate.h
index 4ed35fc..0f54f60 100644
--- a/JavaScriptCore/runtime/JSImmediate.h
+++ b/JavaScriptCore/runtime/JSImmediate.h
@@ -22,8 +22,6 @@
#ifndef JSImmediate_h
#define JSImmediate_h
-#include <wtf/Platform.h>
-
#if !USE(JSVALUE32_64)
#include <wtf/Assertions.h>
diff --git a/JavaScriptCore/runtime/JSNumberCell.cpp b/JavaScriptCore/runtime/JSNumberCell.cpp
index f1009b9..a61c751 100644
--- a/JavaScriptCore/runtime/JSNumberCell.cpp
+++ b/JavaScriptCore/runtime/JSNumberCell.cpp
@@ -57,11 +57,6 @@ UString JSNumberCell::toString(ExecState*) const
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));
diff --git a/JavaScriptCore/runtime/JSNumberCell.h b/JavaScriptCore/runtime/JSNumberCell.h
index bcb506b..cdd2d8c 100644
--- a/JavaScriptCore/runtime/JSNumberCell.h
+++ b/JavaScriptCore/runtime/JSNumberCell.h
@@ -62,7 +62,6 @@ namespace JSC {
virtual UString toString(ExecState*) const;
virtual JSObject* toObject(ExecState*) const;
- virtual UString toThisString(ExecState*) const;
virtual JSObject* toThisObject(ExecState*) const;
virtual JSValue getJSNumber();
diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp
index d69a8da..f6c6b5f 100644
--- a/JavaScriptCore/runtime/JSONObject.cpp
+++ b/JavaScriptCore/runtime/JSONObject.cpp
@@ -31,6 +31,7 @@
#include "ExceptionHelpers.h"
#include "JSArray.h"
#include "LiteralParser.h"
+#include "Lookup.h"
#include "PropertyNameArray.h"
#include "StringBuilder.h"
#include <wtf/MathExtras.h>
@@ -868,4 +869,12 @@ JSValue JSC_HOST_CALL JSONProtoFuncStringify(ExecState* exec, JSObject*, JSValue
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
diff --git a/JavaScriptCore/runtime/JSONObject.h b/JavaScriptCore/runtime/JSONObject.h
index 905e4bc..7a9e0a4 100644
--- a/JavaScriptCore/runtime/JSONObject.h
+++ b/JavaScriptCore/runtime/JSONObject.h
@@ -57,6 +57,8 @@ namespace JSC {
static const ClassInfo info;
};
+ UString JSONStringify(ExecState* exec, JSValue value, unsigned indent);
+
} // namespace JSC
#endif // JSONObject_h
diff --git a/JavaScriptCore/runtime/JSObject.h b/JavaScriptCore/runtime/JSObject.h
index 2b31a65..64a1118 100644
--- a/JavaScriptCore/runtime/JSObject.h
+++ b/JavaScriptCore/runtime/JSObject.h
@@ -26,6 +26,7 @@
#include "ArgList.h"
#include "ClassInfo.h"
#include "CommonIdentifiers.h"
+#include "Completion.h"
#include "CallFrame.h"
#include "JSCell.h"
#include "JSNumberCell.h"
@@ -35,6 +36,7 @@
#include "ScopeChain.h"
#include "Structure.h"
#include "JSGlobalData.h"
+#include "JSString.h"
#include <wtf/StdLibExtras.h>
namespace JSC {
@@ -194,9 +196,10 @@ namespace JSC {
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 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(); }
@@ -436,12 +439,20 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
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 (!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;
}
@@ -468,7 +479,8 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
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;
@@ -481,14 +493,28 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
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));
- 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);
+ putDirectOffset(offset, value);
return;
}
@@ -510,7 +536,8 @@ inline void JSObject::putDirectInternal(const Identifier& propertyName, JSValue
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);
}
@@ -685,6 +712,18 @@ ALWAYS_INLINE void JSObject::markChildrenDirect(MarkStack& markStack)
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
diff --git a/JavaScriptCore/runtime/JSPropertyNameIterator.h b/JavaScriptCore/runtime/JSPropertyNameIterator.h
index 3f533a0..01700ac 100644
--- a/JavaScriptCore/runtime/JSPropertyNameIterator.h
+++ b/JavaScriptCore/runtime/JSPropertyNameIterator.h
@@ -67,8 +67,13 @@ namespace JSC {
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(); }
@@ -76,7 +81,7 @@ namespace JSC {
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;
diff --git a/JavaScriptCore/runtime/JSString.cpp b/JavaScriptCore/runtime/JSString.cpp
index a72457e..fbc7d72 100644
--- a/JavaScriptCore/runtime/JSString.cpp
+++ b/JavaScriptCore/runtime/JSString.cpp
@@ -51,7 +51,7 @@ void JSString::resolveRope(ExecState* exec) const
m_value = newImpl;
else {
for (unsigned i = 0; i < m_fiberCount; ++i) {
- m_other.m_fibers[i]->deref();
+ RopeImpl::deref(m_other.m_fibers[i]);
m_other.m_fibers[i] = 0;
}
m_fiberCount = 0;
@@ -62,15 +62,15 @@ void JSString::resolveRope(ExecState* exec) const
}
UChar* position = buffer + m_length;
- // Start with the current Rope.
- Vector<Rope::Fiber, 32> workQueue;
- Rope::Fiber currentFiber;
+ // 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) {
- if (currentFiber->isRope()) {
- Rope* rope = static_cast<URopeImpl*>(currentFiber);
+ 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).
unsigned fiberCountMinusOne = rope->fiberCount() - 1;
@@ -81,14 +81,14 @@ void JSString::resolveRope(ExecState* exec) const
UStringImpl* string = static_cast<UStringImpl*>(currentFiber);
unsigned length = string->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);
for (unsigned i = 0; i < m_fiberCount; ++i) {
- m_other.m_fibers[i]->deref();
+ RopeImpl::deref(m_other.m_fibers[i]);
m_other.m_fibers[i] = 0;
}
m_fiberCount = 0;
@@ -104,6 +104,18 @@ void JSString::resolveRope(ExecState* exec) const
}
}
+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);
@@ -131,16 +143,6 @@ UString JSString::toString(ExecState* exec) const
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);
@@ -187,7 +189,7 @@ bool JSString::getStringPropertyDescriptor(ExecState* exec, const Identifier& pr
bool isStrictUInt32;
unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
if (isStrictUInt32 && i < m_length) {
- descriptor.setDescriptor(jsSingleCharacterSubstring(exec, value(exec), i), DontDelete | ReadOnly);
+ descriptor.setDescriptor(getIndex(exec, i), DontDelete | ReadOnly);
return true;
}
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index 0162282..b1dccfa 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -29,6 +29,7 @@
#include "JSNumberCell.h"
#include "PropertyDescriptor.h"
#include "PropertySlot.h"
+#include "RopeImpl.h"
namespace JSC {
@@ -41,7 +42,6 @@ namespace JSC {
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);
@@ -67,19 +67,17 @@ namespace JSC {
friend class JIT;
friend class JSGlobalData;
- typedef URopeImpl Rope;
-
class RopeBuilder {
public:
RopeBuilder(unsigned fiberCount)
: m_index(0)
- , m_rope(Rope::tryCreateUninitialized(fiberCount))
+ , m_rope(RopeImpl::tryCreateUninitialized(fiberCount))
{
}
bool isOutOfMemory() { return !m_rope; }
- void append(Rope::Fiber& fiber)
+ void append(RopeImpl::Fiber& fiber)
{
ASSERT(m_rope);
m_rope->initializeFiber(m_index, fiber);
@@ -98,7 +96,7 @@ namespace JSC {
append(jsString->string());
}
- PassRefPtr<Rope> release()
+ PassRefPtr<RopeImpl> release()
{
ASSERT(m_index == m_rope->fiberCount());
return m_rope.release();
@@ -108,7 +106,7 @@ namespace JSC {
private:
unsigned m_index;
- RefPtr<Rope> m_rope;
+ RefPtr<RopeImpl> m_rope;
};
ALWAYS_INLINE JSString(JSGlobalData* globalData, const UString& value)
@@ -117,6 +115,7 @@ namespace JSC {
, m_value(value)
, m_fiberCount(0)
{
+ ASSERT(!m_value.isNull());
Heap::heap(this)->reportExtraMemoryCost(value.cost());
}
@@ -127,6 +126,7 @@ namespace JSC {
, m_value(value)
, m_fiberCount(0)
{
+ ASSERT(!m_value.isNull());
}
JSString(JSGlobalData* globalData, PassRefPtr<UString::Rep> value, HasOtherOwnerType)
: JSCell(globalData->stringStructure.get())
@@ -134,8 +134,9 @@ namespace JSC {
, m_value(value)
, m_fiberCount(0)
{
+ ASSERT(!m_value.isNull());
}
- JSString(JSGlobalData* globalData, PassRefPtr<Rope> rope)
+ JSString(JSGlobalData* globalData, PassRefPtr<RopeImpl> rope)
: JSCell(globalData->stringStructure.get())
, m_length(rope->length())
, m_fiberCount(1)
@@ -203,6 +204,7 @@ namespace JSC {
, m_value(value)
, m_fiberCount(0)
{
+ ASSERT(!m_value.isNull());
// nasty hack because we can't union non-POD types
m_other.m_finalizerCallback = finalizer;
m_other.m_finalizerContext = context;
@@ -213,7 +215,7 @@ namespace JSC {
{
ASSERT(vptr() == JSGlobalData::jsStringVPtr);
for (unsigned i = 0; i < m_fiberCount; ++i)
- m_other.m_fibers[i]->deref();
+ RopeImpl::deref(m_other.m_fibers[i]);
if (!m_fiberCount && m_other.m_finalizerCallback)
m_other.m_finalizerCallback(this, m_other.m_finalizerContext);
@@ -240,6 +242,7 @@ namespace JSC {
bool canGetIndex(unsigned i) { return i < m_length; }
JSString* getIndex(ExecState*, unsigned);
+ JSString* getIndexSlowCase(ExecState*, unsigned);
static PassRefPtr<Structure> createStructure(JSValue proto) { return Structure::create(proto, TypeInfo(StringType, OverridesGetOwnPropertySlot | NeedsThisConversion), AnonymousSlotCount); }
@@ -264,7 +267,7 @@ namespace JSC {
{
if (jsString->isRope()) {
for (unsigned i = 0; i < jsString->m_fiberCount; ++i) {
- Rope::Fiber fiber = jsString->m_other.m_fibers[i];
+ RopeImpl::Fiber fiber = jsString->m_other.m_fibers[i];
fiber->ref();
m_other.m_fibers[index++] = fiber;
}
@@ -297,8 +300,6 @@ namespace JSC {
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&);
@@ -307,7 +308,7 @@ namespace JSC {
static const unsigned s_maxInternalRopeLength = 3;
- // A string is represented either by a UString or a Rope.
+ // A string is represented either by a UString or a RopeImpl.
unsigned m_length;
mutable UString m_value;
mutable unsigned m_fiberCount;
@@ -315,7 +316,7 @@ namespace JSC {
struct JSStringFinalizerStruct {
JSStringFinalizerStruct() : m_finalizerCallback(0) {}
union {
- mutable Rope::Fiber m_fibers[s_maxInternalRopeLength];
+ mutable RopeImpl::Fiber m_fibers[s_maxInternalRopeLength];
struct {
JSStringFinalizerCallback m_finalizerCallback;
void* m_finalizerContext;
@@ -365,8 +366,9 @@ namespace JSC {
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)
@@ -391,7 +393,10 @@ namespace JSC {
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, value(exec), i);
}
inline JSString* jsString(JSGlobalData* globalData, const UString& s)
@@ -445,7 +450,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* 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); }
@@ -461,7 +465,7 @@ namespace JSC {
bool isStrictUInt32;
unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
if (isStrictUInt32 && i < m_length) {
- slot.setValue(jsSingleCharacterSubstring(exec, value(exec), i));
+ slot.setValue(getIndex(exec, i));
return true;
}
@@ -471,7 +475,7 @@ namespace JSC {
ALWAYS_INLINE bool JSString::getStringPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
{
if (propertyName < m_length) {
- slot.setValue(jsSingleCharacterSubstring(exec, value(exec), propertyName));
+ slot.setValue(getIndex(exec, propertyName));
return true;
}
@@ -482,11 +486,6 @@ namespace JSC {
// --- 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())
diff --git a/JavaScriptCore/runtime/JSStringBuilder.h b/JavaScriptCore/runtime/JSStringBuilder.h
index 2b11736..8f208a1 100644
--- a/JavaScriptCore/runtime/JSStringBuilder.h
+++ b/JavaScriptCore/runtime/JSStringBuilder.h
@@ -28,31 +28,59 @@
#include "ExceptionHelpers.h"
#include "JSString.h"
-#include "StringBuilder.h"
+#include "Vector.h"
namespace JSC {
-class JSStringBuilder : public StringBuilder {
+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));
}
-private:
- // Make attempts to call this compile error - if you only wanted a UString,
- // Why didn't you just use a StringBuilder?! (This may change, maybe at some
- // point in the future we'll need to start building a string not knowing whether
- // we'll want a UString or a JSValue - but until we have this requirement,
- // block this).
- UString build()
- {
- ASSERT_NOT_REACHED();
- return StringBuilder::build();
- }
+protected:
+ Vector<UChar, 64> buffer;
+ bool m_okay;
};
template<typename StringType1, typename StringType2>
diff --git a/JavaScriptCore/runtime/JSTypeInfo.h b/JavaScriptCore/runtime/JSTypeInfo.h
index 7c89600..e225bc7 100644
--- a/JavaScriptCore/runtime/JSTypeInfo.h
+++ b/JavaScriptCore/runtime/JSTypeInfo.h
@@ -50,6 +50,8 @@ namespace JSC {
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;
@@ -57,7 +59,7 @@ namespace JSC {
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; }
@@ -69,8 +71,8 @@ namespace JSC {
unsigned flags() const { return m_flags; }
private:
- JSType m_type;
- unsigned m_flags;
+ unsigned char m_type;
+ unsigned char m_flags;
};
}
diff --git a/JavaScriptCore/runtime/JSValue.h b/JavaScriptCore/runtime/JSValue.h
index 6da921f..b37adc0 100644
--- a/JavaScriptCore/runtime/JSValue.h
+++ b/JavaScriptCore/runtime/JSValue.h
@@ -188,7 +188,7 @@ namespace JSC {
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);
diff --git a/JavaScriptCore/runtime/JSZombie.h b/JavaScriptCore/runtime/JSZombie.h
index 8b33ea6..711f673 100644
--- a/JavaScriptCore/runtime/JSZombie.h
+++ b/JavaScriptCore/runtime/JSZombie.h
@@ -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 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; }
diff --git a/JavaScriptCore/runtime/Lookup.h b/JavaScriptCore/runtime/Lookup.h
index e673c09..995aeee 100644
--- a/JavaScriptCore/runtime/Lookup.h
+++ b/JavaScriptCore/runtime/Lookup.h
@@ -181,7 +181,7 @@ namespace JSC {
if (entry->attributes() & Function)
setUpStaticFunctionSlot(exec, entry, thisObj, propertyName, slot);
else
- slot.setCustom(thisObj, entry->propertyGetter());
+ slot.setCacheableCustom(thisObj, entry->propertyGetter());
return true;
}
@@ -258,7 +258,7 @@ namespace JSC {
ASSERT(!(entry->attributes() & Function));
- slot.setCustom(thisObj, entry->propertyGetter());
+ slot.setCacheableCustom(thisObj, entry->propertyGetter());
return true;
}
diff --git a/JavaScriptCore/runtime/MathObject.cpp b/JavaScriptCore/runtime/MathObject.cpp
index 8f22fba..16d32a0 100644
--- a/JavaScriptCore/runtime/MathObject.cpp
+++ b/JavaScriptCore/runtime/MathObject.cpp
@@ -21,6 +21,7 @@
#include "config.h"
#include "MathObject.h"
+#include "Lookup.h"
#include "ObjectPrototype.h"
#include "Operations.h"
#include <time.h>
@@ -216,8 +217,6 @@ JSValue JSC_HOST_CALL mathProtoFuncRandom(ExecState* exec, JSObject*, JSValue, c
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);
double integer = ceil(arg);
return jsNumber(exec, integer - (integer - arg > 0.5));
}
diff --git a/JavaScriptCore/runtime/NumberConstructor.cpp b/JavaScriptCore/runtime/NumberConstructor.cpp
index cc6c51d..0b7e821 100644
--- a/JavaScriptCore/runtime/NumberConstructor.cpp
+++ b/JavaScriptCore/runtime/NumberConstructor.cpp
@@ -22,6 +22,7 @@
#include "config.h"
#include "NumberConstructor.h"
+#include "Lookup.h"
#include "NumberObject.h"
#include "NumberPrototype.h"
@@ -29,11 +30,11 @@ namespace JSC {
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
@@ -73,27 +74,27 @@ bool NumberConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifi
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);
}
-static JSValue numberConstructorNegInfinity(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorNegInfinity(ExecState* exec, JSValue, const Identifier&)
{
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);
}
-static JSValue numberConstructorMaxValue(ExecState* exec, const Identifier&, const PropertySlot&)
+static JSValue numberConstructorMaxValue(ExecState* exec, JSValue, const Identifier&)
{
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);
}
diff --git a/JavaScriptCore/runtime/NumericStrings.h b/JavaScriptCore/runtime/NumericStrings.h
index c0696a4..89235af 100644
--- a/JavaScriptCore/runtime/NumericStrings.h
+++ b/JavaScriptCore/runtime/NumericStrings.h
@@ -45,6 +45,8 @@ namespace JSC {
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;
@@ -53,6 +55,17 @@ namespace JSC {
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;
@@ -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<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<unsigned> unsignedCache[cacheSize];
+ UString smallIntCache[cacheSize];
};
} // namespace JSC
diff --git a/JavaScriptCore/runtime/PropertyNameArray.cpp b/JavaScriptCore/runtime/PropertyNameArray.cpp
index 4937b7c..6b24669 100644
--- a/JavaScriptCore/runtime/PropertyNameArray.cpp
+++ b/JavaScriptCore/runtime/PropertyNameArray.cpp
@@ -30,7 +30,7 @@ static const size_t setThreshold = 20;
void PropertyNameArray::add(UString::Rep* identifier)
{
- ASSERT(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) {
diff --git a/JavaScriptCore/runtime/PropertySlot.cpp b/JavaScriptCore/runtime/PropertySlot.cpp
index 8b6ceb9..2306a11 100644
--- a/JavaScriptCore/runtime/PropertySlot.cpp
+++ b/JavaScriptCore/runtime/PropertySlot.cpp
@@ -26,19 +26,19 @@
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;
- CallType callType = slot.m_data.getterFunc->getCallData(callData);
+ CallType callType = m_data.getterFunc->getCallData(callData);
if (callType == CallTypeHost)
- return callData.native.function(exec, slot.m_data.getterFunc, slot.thisValue(), 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?
- return asFunction(slot.m_data.getterFunc)->call(exec, slot.thisValue(), exec->emptyList());
+ return asFunction(m_data.getterFunc)->call(exec, thisValue(), exec->emptyList());
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/PropertySlot.h b/JavaScriptCore/runtime/PropertySlot.h
index a364e42..de9ddc9 100644
--- a/JavaScriptCore/runtime/PropertySlot.h
+++ b/JavaScriptCore/runtime/PropertySlot.h
@@ -34,10 +34,20 @@ namespace JSC {
#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:
+ enum CachedPropertyType {
+ Uncacheable,
+ Getter,
+ Custom,
+ Value
+ };
+
PropertySlot()
+ : m_cachedPropertyType(Uncacheable)
{
clearBase();
clearOffset();
@@ -46,12 +56,14 @@ namespace JSC {
explicit PropertySlot(const JSValue base)
: m_slotBase(base)
+ , m_cachedPropertyType(Uncacheable)
{
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
{
@@ -59,7 +71,11 @@ namespace JSC {
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
@@ -68,12 +84,16 @@ namespace JSC {
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 isGetter() const { return m_isGetter; }
- bool isCacheable() const { return m_isCacheable; }
- bool isCacheableValue() const { return m_isCacheable && !m_isGetter; }
+ 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());
@@ -104,8 +124,7 @@ namespace JSC {
m_slotBase = slotBase;
m_data.valueSlot = valueSlot;
m_offset = offset;
- m_isCacheable = true;
- m_isGetter = false;
+ m_cachedPropertyType = Value;
}
void setValue(JSValue value)
@@ -132,14 +151,26 @@ namespace JSC {
ASSERT(slotBase);
ASSERT(getValue);
m_getValue = getValue;
+ m_getIndexValue = 0;
m_slotBase = slotBase;
}
-
- void setCustomIndex(JSValue slotBase, unsigned index, GetValueFunc getValue)
+
+ void setCacheableCustom(JSValue slotBase, GetValueFunc 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;
}
@@ -148,21 +179,19 @@ namespace JSC {
{
ASSERT(getterFunc);
m_thisValue = m_slotBase;
- m_getValue = functionGetter;
+ m_getValue = GETTER_FUNCTION_MARKER;
m_data.getterFunc = getterFunc;
- m_isGetter = true;
}
void setCacheableGetterSlot(JSValue slotBase, JSObject* getterFunc, unsigned offset)
{
ASSERT(getterFunc);
- m_getValue = functionGetter;
+ m_getValue = GETTER_FUNCTION_MARKER;
m_thisValue = m_slotBase;
m_slotBase = slotBase;
m_data.getterFunc = getterFunc;
m_offset = offset;
- m_isCacheable = true;
- m_isGetter = true;
+ m_cachedPropertyType = Getter;
}
void setUndefined()
@@ -201,17 +230,23 @@ 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.)
m_offset = 0;
- m_isCacheable = false;
- m_isGetter = false;
+ m_cachedPropertyType = Uncacheable;
}
unsigned index() const { return m_data.index; }
JSValue thisValue() const { return m_thisValue; }
+
+ GetValueFunc customGetter() const
+ {
+ ASSERT(m_cachedPropertyType == Custom);
+ return m_getValue;
+ }
private:
- static JSValue functionGetter(ExecState*, const Identifier&, const PropertySlot&);
+ JSValue functionGetter(ExecState*) const;
GetValueFunc m_getValue;
+ GetIndexValueFunc m_getIndexValue;
JSValue m_slotBase;
union {
@@ -225,8 +260,7 @@ namespace JSC {
JSValue m_thisValue;
size_t m_offset;
- bool m_isCacheable : 1;
- bool m_isGetter : 1;
+ CachedPropertyType m_cachedPropertyType;
};
} // namespace JSC
diff --git a/JavaScriptCore/runtime/RegExp.cpp b/JavaScriptCore/runtime/RegExp.cpp
index 85d41ee..f097943 100644
--- a/JavaScriptCore/runtime/RegExp.cpp
+++ b/JavaScriptCore/runtime/RegExp.cpp
@@ -40,20 +40,12 @@
#else
-#if ENABLE(WREC)
-#include "JIT.h"
-#include "WRECGenerator.h"
-#endif
#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)
@@ -164,18 +156,9 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
#else
-void RegExp::compile(JSGlobalData* globalData)
+void RegExp::compile(JSGlobalData*)
{
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);
@@ -191,36 +174,6 @@ int RegExp::match(const UString& s, int startOffset, Vector<int, 32>* ovector)
if (static_cast<unsigned>(startOffset) > s.size() || s.isNull())
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.
diff --git a/JavaScriptCore/runtime/RegExp.h b/JavaScriptCore/runtime/RegExp.h
index 61ab0bc..695b688 100644
--- a/JavaScriptCore/runtime/RegExp.h
+++ b/JavaScriptCore/runtime/RegExp.h
@@ -23,7 +23,6 @@
#define RegExp_h
#include "UString.h"
-#include "WREC.h"
#include "ExecutableAllocator.h"
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
@@ -74,10 +73,6 @@ namespace JSC {
#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
};
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
index 6f00142..3a67ae6 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -27,6 +27,7 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "JSString.h"
+#include "Lookup.h"
#include "ObjectPrototype.h"
#include "RegExpMatchesArray.h"
#include "RegExpObject.h"
@@ -35,21 +36,21 @@
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);
@@ -113,17 +114,17 @@ RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate
memcpy(d->lastOvector().data(), data->lastOvector().data(), offsetVectorSize * sizeof(int));
// d->multiline is not needed, and remains uninitialized
- setLazyCreationData(d);
+ setSubclassData(d);
}
RegExpMatchesArray::~RegExpMatchesArray()
{
- delete static_cast<RegExpConstructorPrivate*>(lazyCreationData());
+ delete static_cast<RegExpConstructorPrivate*>(subclassData());
}
void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
{
- RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(lazyCreationData());
+ RegExpConstructorPrivate* d = static_cast<RegExpConstructorPrivate*>(subclassData());
ASSERT(d);
unsigned lastNumSubpatterns = d->lastNumSubPatterns;
@@ -141,7 +142,7 @@ void RegExpMatchesArray::fillArrayInstance(ExecState* exec)
JSArray::put(exec, exec->propertyNames().input, jsString(exec, d->input), slot);
delete d;
- setLazyCreationData(0);
+ setSubclassData(0);
}
JSObject* RegExpConstructor::arrayOfMatches(ExecState* exec) const
@@ -195,79 +196,79 @@ bool RegExpConstructor::getOwnPropertyDescriptor(ExecState* exec, const Identifi
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)
diff --git a/JavaScriptCore/runtime/RegExpMatchesArray.h b/JavaScriptCore/runtime/RegExpMatchesArray.h
index 38d3cb4..b823621 100644
--- a/JavaScriptCore/runtime/RegExpMatchesArray.h
+++ b/JavaScriptCore/runtime/RegExpMatchesArray.h
@@ -32,56 +32,56 @@ namespace JSC {
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)
{
- if (lazyCreationData())
+ if (subclassData())
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)
{
- if (lazyCreationData())
+ if (subclassData())
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)
{
- if (lazyCreationData())
+ if (subclassData())
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)
{
- if (lazyCreationData())
+ if (subclassData())
fillArrayInstance(exec);
JSArray::getOwnPropertyNames(exec, arr, mode);
}
diff --git a/JavaScriptCore/runtime/RegExpObject.cpp b/JavaScriptCore/runtime/RegExpObject.cpp
index 42bfcef..bc74924 100644
--- a/JavaScriptCore/runtime/RegExpObject.cpp
+++ b/JavaScriptCore/runtime/RegExpObject.cpp
@@ -25,16 +25,17 @@
#include "JSArray.h"
#include "JSGlobalObject.h"
#include "JSString.h"
+#include "Lookup.h"
#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
@@ -77,29 +78,29 @@ bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& p
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)
diff --git a/JavaScriptCore/wrec/Quantifier.h b/JavaScriptCore/runtime/RopeImpl.cpp
index 3da74cd..a3760e6 100644
--- a/JavaScriptCore/wrec/Quantifier.h
+++ b/JavaScriptCore/runtime/RopeImpl.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * 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
@@ -23,44 +23,40 @@
* 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
+#include "config.h"
+#include "RopeImpl.h"
+
+namespace JSC {
+
+void RopeImpl::derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue)
+{
+ unsigned length = fiberCount();
+ for (unsigned i = 0; i < length; ++i) {
+ Fiber& fiber = 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/JavaScriptCore/runtime/RopeImpl.h b/JavaScriptCore/runtime/RopeImpl.h
new file mode 100644
index 0000000..6fbc595
--- /dev/null
+++ b/JavaScriptCore/runtime/RopeImpl.h
@@ -0,0 +1,88 @@
+/*
+ * 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;
+ }
+
+ void initializeFiber(unsigned &index, Fiber fiber)
+ {
+ m_fibers[index++] = fiber;
+ fiber->ref();
+ m_length += fiber->length();
+ }
+
+ unsigned fiberCount() { return m_fiberCount; }
+ Fiber& fibers(unsigned index) { return m_fibers[index]; }
+
+ ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) destructNonRecursive(); }
+
+ 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();
+ }
+
+private:
+ RopeImpl(unsigned fiberCount) : StringImplBase(ConstructNonStringImpl), m_fiberCount(fiberCount) {}
+
+ void destructNonRecursive();
+ void derefFibersNonRecursive(Vector<RopeImpl*, 32>& workQueue);
+
+ bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; }
+
+ unsigned m_fiberCount;
+ Fiber m_fibers[1];
+};
+
+}
+
+#endif
diff --git a/JavaScriptCore/runtime/SmallStrings.cpp b/JavaScriptCore/runtime/SmallStrings.cpp
index 78bd4e4..0f5df4a 100644
--- a/JavaScriptCore/runtime/SmallStrings.cpp
+++ b/JavaScriptCore/runtime/SmallStrings.cpp
@@ -43,10 +43,10 @@ class SmallStringsStorage : public Noncopyable {
public:
SmallStringsStorage();
- UString::Rep* rep(unsigned char character) { return &m_reps[character]; }
+ UString::Rep* rep(unsigned char character) { return m_reps[character].get(); }
private:
- UString::Rep m_reps[numCharactersToStore];
+ RefPtr<UString::Rep> m_reps[numCharactersToStore];
};
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;
- new (&m_reps[i]) UString::Rep(&characterBuffer[i], 1, PassRefPtr<UStringImpl>(baseString));
+ m_reps[i] = UStringImpl::create(baseString, i, 1);
}
}
diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/StringBuilder.h
index 27dbbd7..59b01e0 100644
--- a/JavaScriptCore/runtime/StringBuilder.h
+++ b/JavaScriptCore/runtime/StringBuilder.h
@@ -69,8 +69,7 @@ public:
UString build()
{
buffer.shrinkToFit();
- if (buffer.size() && !buffer.data())
- CRASH();
+ ASSERT(buffer.data() || !buffer.size());
return UString::adopt(buffer);
}
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index bef4083..345378e 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -29,6 +29,7 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "JSStringBuilder.h"
+#include "Lookup.h"
#include "ObjectPrototype.h"
#include "Operations.h"
#include "PropertyNameArray.h"
diff --git a/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp
index ebf8a4c..6f23c7d 100644
--- a/JavaScriptCore/runtime/Structure.cpp
+++ b/JavaScriptCore/runtime/Structure.cpp
@@ -265,9 +265,7 @@ Structure::~Structure()
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;
diff --git a/JavaScriptCore/runtime/Terminator.h b/JavaScriptCore/runtime/Terminator.h
new file mode 100644
index 0000000..6b0f236
--- /dev/null
+++ b/JavaScriptCore/runtime/Terminator.h
@@ -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
diff --git a/JavaScriptCore/runtime/TimeoutChecker.cpp b/JavaScriptCore/runtime/TimeoutChecker.cpp
index 250fdaf..2dc1028 100644
--- a/JavaScriptCore/runtime/TimeoutChecker.cpp
+++ b/JavaScriptCore/runtime/TimeoutChecker.cpp
@@ -84,6 +84,13 @@ static inline unsigned getCPUTime()
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.
diff --git a/JavaScriptCore/runtime/UString.cpp b/JavaScriptCore/runtime/UString.cpp
index 1684ec2..ce91040 100644
--- a/JavaScriptCore/runtime/UString.cpp
+++ b/JavaScriptCore/runtime/UString.cpp
@@ -57,108 +57,15 @@ namespace JSC {
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_empty;
-
-UString::Rep* UString::s_nullRep;
+// The null string is immutable, except for refCount.
UString* UString::s_nullUString;
void initializeUString()
{
- UStringImpl::s_empty = new UStringImpl(&sharedEmptyChar, 0, UStringImpl::ConstructStaticString);
+ // UStringImpl::empty() does not construct its static string in a threadsafe fashion,
+ // so ensure it has been initialized from here.
+ UStringImpl::empty();
- UString::s_nullRep = new UStringImpl(0, 0, UStringImpl::ConstructStaticString);
UString::s_nullUString = new UString;
}
@@ -173,11 +80,8 @@ UString::UString(const char* c, unsigned 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::from(int i)
@@ -242,7 +146,7 @@ UString UString::from(long long i)
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);
@@ -297,29 +201,6 @@ UString UString::from(double d)
return UString(buffer, length);
}
-bool UString::getCString(CStringBuffer& buffer) const
-{
- unsigned length = size();
- unsigned 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;
@@ -373,11 +254,7 @@ double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) co
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))
- return NaN;
+ CString s = UTF8String();
const char* c = s.data();
// skip leading white space
@@ -498,7 +375,7 @@ uint32_t UString::toStrictUInt32(bool* ok) const
unsigned len = m_rep->length();
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.
@@ -548,7 +425,7 @@ unsigned UString::find(const UString& f, unsigned pos) const
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 NotFound;
}
@@ -565,7 +442,7 @@ unsigned UString::find(const UString& f, unsigned pos) const
++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 NotFound;
@@ -576,7 +453,7 @@ unsigned UString::find(UChar ch, unsigned pos) const
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 NotFound;
@@ -596,7 +473,7 @@ unsigned UString::rfind(const UString& f, unsigned pos) const
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 NotFound;
@@ -610,7 +487,7 @@ unsigned UString::rfind(UChar ch, unsigned pos) const
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 NotFound;
@@ -710,20 +587,6 @@ int compare(const UString& s1, const UString& s2)
return (l1 > l2) ? 1 : -1;
}
-bool equal(const UString::Rep* r, const UString::Rep* b)
-{
- unsigned length = r->length();
- if (length != b->length())
- return false;
- const UChar* d = r->data();
- const UChar* s = b->data();
- for (unsigned 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.
diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h
index 75b43b7..da1065e 100644
--- a/JavaScriptCore/runtime/UString.h
+++ b/JavaScriptCore/runtime/UString.h
@@ -33,6 +33,7 @@
#include <wtf/PassRefPtr.h>
#include <wtf/RefPtr.h>
#include <wtf/Vector.h>
+#include <wtf/text/CString.h>
#include <wtf/unicode/Unicode.h>
namespace JSC {
@@ -40,39 +41,6 @@ namespace JSC {
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;
@@ -80,7 +48,7 @@ namespace JSC {
typedef UStringImpl Rep;
public:
- UString();
+ UString() {}
UString(const char*); // Constructor for null-terminated string.
UString(const char*, unsigned length);
UString(const UChar*, unsigned length);
@@ -97,10 +65,6 @@ namespace JSC {
{
}
- ~UString()
- {
- }
-
template<size_t inlineCapacity>
static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
{
@@ -109,12 +73,10 @@ namespace JSC {
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);
- 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;
@@ -129,14 +91,24 @@ namespace JSC {
*/
CString UTF8String(bool strict = false) const;
- const UChar* data() const { return m_rep->data(); }
+ const UChar* data() const
+ {
+ if (!m_rep)
+ return 0;
+ return m_rep->characters();
+ }
- bool isNull() const { return m_rep == s_nullRep; }
- bool isEmpty() const { return !m_rep->length(); }
+ unsigned size() const
+ {
+ if (!m_rep)
+ return 0;
+ return m_rep->length();
+ }
- bool is8Bit() const;
+ bool isNull() const { return !m_rep; }
+ bool isEmpty() const { return !m_rep || !m_rep->length(); }
- unsigned size() const { return m_rep->length(); }
+ bool is8Bit() const;
UChar operator[](unsigned pos) const;
@@ -165,15 +137,18 @@ namespace JSC {
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:
RefPtr<Rep> m_rep;
- JS_EXPORTDATA static Rep* s_nullRep;
static UString* s_nullUString;
friend void initializeUString();
@@ -228,11 +203,6 @@ namespace JSC {
int compare(const UString&, const UString&);
- inline UString::UString()
- : m_rep(s_nullRep)
- {
- }
-
// 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
@@ -657,7 +627,7 @@ namespace WTF {
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;
};
@@ -665,22 +635,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;
- 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;
};
- 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
diff --git a/JavaScriptCore/runtime/UStringImpl.cpp b/JavaScriptCore/runtime/UStringImpl.cpp
deleted file mode 100644
index b7d9a40..0000000
--- a/JavaScriptCore/runtime/UStringImpl.cpp
+++ /dev/null
@@ -1,152 +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 {
-
-PassRefPtr<UStringImpl> UStringImpl::create(const char* c)
-{
- ASSERT(c);
-
- if (!c[0])
- return &UStringImpl::empty();
-
- size_t length = strlen(c);
- UChar* d;
- PassRefPtr<UStringImpl> result = UStringImpl::createUninitialized(length, d);
- 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;
-}
-
-PassRefPtr<UStringImpl> UStringImpl::create(const char* c, unsigned length)
-{
- ASSERT(c);
-
- if (!length)
- return &UStringImpl::empty();
-
- UChar* d;
- PassRefPtr<UStringImpl> result = UStringImpl::createUninitialized(length, d);
- for (unsigned 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;
-}
-
-PassRefPtr<UStringImpl> UStringImpl::create(const UChar* buffer, unsigned length)
-{
- UChar* newBuffer;
- PassRefPtr<UStringImpl> impl = createUninitialized(length, newBuffer);
- copyChars(newBuffer, buffer, length);
- return impl;
-}
-
-SharedUChar* UStringImpl::baseSharedBuffer()
-{
- ASSERT((bufferOwnership() == BufferShared)
- || ((bufferOwnership() == BufferOwned) && !m_buffer));
-
- if (bufferOwnership() != BufferShared) {
- m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared;
- m_bufferShared = SharedUChar::create(new OwnFastMallocPtr<UChar>(m_data)).releaseRef();
- }
-
- return m_bufferShared;
-}
-
-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_bufferSubstring->deref();
- else {
- ASSERT(bufferOwnership() == BufferShared);
- m_bufferShared->deref();
- }
- }
-}
-
-void URopeImpl::derefFibersNonRecursive(Vector<URopeImpl*, 32>& workQueue)
-{
- unsigned length = fiberCount();
- for (unsigned i = 0; i < length; ++i) {
- Fiber& fiber = fibers(i);
- if (fiber->isRope()) {
- URopeImpl* nextRope = static_cast<URopeImpl*>(fiber);
- if (nextRope->hasOneRef())
- workQueue.append(nextRope);
- else
- nextRope->deref();
- } else
- static_cast<UStringImpl*>(fiber)->deref();
- }
-}
-
-void URopeImpl::destructNonRecursive()
-{
- Vector<URopeImpl*, 32> workQueue;
-
- derefFibersNonRecursive(workQueue);
- delete this;
-
- while (!workQueue.isEmpty()) {
- URopeImpl* rope = workQueue.last();
- workQueue.removeLast();
- rope->derefFibersNonRecursive(workQueue);
- delete rope;
- }
-}
-
-} // namespace JSC
diff --git a/JavaScriptCore/runtime/UStringImpl.h b/JavaScriptCore/runtime/UStringImpl.h
index 142e01d..08f1fa5 100644
--- a/JavaScriptCore/runtime/UStringImpl.h
+++ b/JavaScriptCore/runtime/UStringImpl.h
@@ -1,359 +1,30 @@
/*
- * 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
-#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 UStringOrRopeImpl : public Noncopyable {
-public:
- bool isRope() { return (m_refCountAndFlags & s_refCountIsRope) == s_refCountIsRope; }
- unsigned length() const { return m_length; }
-
- void ref() { m_refCountAndFlags += s_refCountIncrement; }
- inline void deref();
-
-protected:
- enum BufferOwnership {
- BufferInternal,
- BufferOwned,
- BufferSubstring,
- BufferShared,
- };
-
- using Noncopyable::operator new;
- void* operator new(size_t, void* inPlace) { return inPlace; }
-
- // For SmallStringStorage, which allocates an array and uses an in-place new.
- UStringOrRopeImpl() { }
-
- UStringOrRopeImpl(unsigned length, BufferOwnership ownership)
- : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership)
- , m_length(length)
- {
- ASSERT(!isRope());
- }
-
- enum StaticStringConstructType { ConstructStaticString };
- UStringOrRopeImpl(unsigned length, StaticStringConstructType)
- : m_refCountAndFlags(s_refCountFlagStatic | BufferOwned)
- , m_length(length)
- {
- ASSERT(!isRope());
- }
-
- enum RopeConstructType { ConstructRope };
- UStringOrRopeImpl(RopeConstructType)
- : m_refCountAndFlags(s_refCountIncrement | s_refCountIsRope)
- , m_length(0)
- {
- ASSERT(isRope());
- }
-
- // The bottom 5 bits hold flags, the top 27 bits hold the ref count.
- // When dereferencing UStringImpls we check for the ref count AND the
- // static bit both being zero - static strings are never deleted.
- static const unsigned s_refCountMask = 0xFFFFFFE0;
- static const unsigned s_refCountIncrement = 0x20;
- static const unsigned s_refCountFlagStatic = 0x10;
- static const unsigned s_refCountFlagShouldReportedCost = 0x8;
- static const unsigned s_refCountFlagIsIdentifier = 0x4;
- static const unsigned s_refCountMaskBufferOwnership = 0x3;
- // Use an otherwise invalid permutation of flags (static & shouldReportedCost -
- // static strings do not set shouldReportedCost in the constructor, and this bit
- // is only ever cleared, not set) to identify objects that are ropes.
- static const unsigned s_refCountIsRope = s_refCountFlagStatic | s_refCountFlagShouldReportedCost;
-
- unsigned m_refCountAndFlags;
- unsigned m_length;
-};
-
-class UStringImpl : public UStringOrRopeImpl {
-public:
- template<size_t inlineCapacity>
- static PassRefPtr<UStringImpl> adopt(Vector<UChar, inlineCapacity>& vector)
- {
- if (unsigned length = vector.size()) {
- ASSERT(vector.data());
- return adoptRef(new UStringImpl(vector.releaseBuffer(), length));
- }
- return &empty();
- }
-
- static PassRefPtr<UStringImpl> create(const char* c);
- static PassRefPtr<UStringImpl> create(const char* c, unsigned length);
- static PassRefPtr<UStringImpl> create(const UChar* buffer, unsigned length);
-
- static PassRefPtr<UStringImpl> create(PassRefPtr<UStringImpl> rep, unsigned offset, unsigned 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, unsigned 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(length));
- }
-
- 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(length));
- }
-
- SharedUChar* sharedBuffer();
- UChar* data() const { return m_data; }
- size_t cost()
- {
- // For substrings, return the cost of the base string.
- if (bufferOwnership() == BufferSubstring)
- return m_bufferSubstring->cost();
-
- if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) {
- m_refCountAndFlags &= ~s_refCountFlagShouldReportedCost;
- return m_length;
- }
- return 0;
- }
- 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_refCountAndFlags & s_refCountFlagIsIdentifier; }
- void setIsIdentifier(bool isIdentifier)
- {
- if (isIdentifier)
- m_refCountAndFlags |= s_refCountFlagIsIdentifier;
- else
- m_refCountAndFlags &= ~s_refCountFlagIsIdentifier;
- }
-
- ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) 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, unsigned length) { return WTF::stringHash(s, length); }
- static unsigned computeHash(const char* s, unsigned length) { return WTF::stringHash(s, length); }
- static unsigned computeHash(const char* s) { return WTF::stringHash(s); }
-
- 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:
- // For SmallStringStorage, which allocates an array and uses an in-place new.
- UStringImpl() { }
-
- // Used to construct normal strings with an internal buffer.
- UStringImpl(unsigned length)
- : UStringOrRopeImpl(length, BufferInternal)
- , m_data(reinterpret_cast<UChar*>(this + 1))
- , m_buffer(0)
- , m_hash(0)
- {
- checkConsistency();
- }
-
- // Used to construct normal strings with an external buffer.
- UStringImpl(UChar* data, unsigned length)
- : UStringOrRopeImpl(length, BufferOwned)
- , m_data(data)
- , m_buffer(0)
- , m_hash(0)
- {
- 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.
- UStringImpl(UChar* data, unsigned length, StaticStringConstructType)
- : UStringOrRopeImpl(length, ConstructStaticString)
- , m_data(data)
- , m_buffer(0)
- , m_hash(0)
- {
- checkConsistency();
- }
-
- // Used to create new strings that are a substring of an existing string.
- UStringImpl(UChar* data, unsigned length, PassRefPtr<UStringImpl> base)
- : UStringOrRopeImpl(length, BufferSubstring)
- , m_data(data)
- , m_bufferSubstring(base.releaseRef())
- , m_hash(0)
- {
- // 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_bufferSubstring->length());
- ASSERT(!m_bufferSubstring->isStatic());
- checkConsistency();
- }
-
- // Used to construct new strings sharing an existing shared buffer.
- UStringImpl(UChar* data, unsigned length, PassRefPtr<SharedUChar> sharedBuffer)
- : UStringOrRopeImpl(length, BufferShared)
- , m_data(data)
- , m_bufferShared(sharedBuffer.releaseRef())
- , m_hash(0)
- {
- checkConsistency();
- }
-
- ~UStringImpl();
-
- // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings.
- static const unsigned s_minLengthToShare = 10;
- static const unsigned s_copyCharsInlineCutOff = 20;
-
- UStringImpl* bufferOwnerString() { return (bufferOwnership() == BufferSubstring) ? m_bufferSubstring : this; }
- const UStringImpl* bufferOwnerString() const { return (bufferOwnership() == BufferSubstring) ? m_bufferSubstring : this; }
- SharedUChar* baseSharedBuffer();
- unsigned bufferOwnership() const { return m_refCountAndFlags & s_refCountMaskBufferOwnership; }
- bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; }
-
- // unshared data
- UChar* m_data;
- union {
- void* m_buffer;
- UStringImpl* m_bufferSubstring;
- SharedUChar* m_bufferShared;
- };
- mutable unsigned m_hash;
-
- JS_EXPORTDATA static UStringImpl* s_empty;
-
- friend class JIT;
- friend class SmallStringsStorage;
- friend class UStringOrRopeImpl;
- friend void initializeUString();
-};
-
-class URopeImpl : public UStringOrRopeImpl {
-public:
- // A URopeImpl is composed from a set of smaller strings called Fibers.
- // Each Fiber in a rope is either UStringImpl or another URopeImpl.
- typedef UStringOrRopeImpl* Fiber;
-
- // Creates a URopeImpl comprising of 'fiberCount' Fibers.
- // The URopeImpl is constructed in an uninitialized state - initialize must be called for each Fiber in the URopeImpl.
- static PassRefPtr<URopeImpl> tryCreateUninitialized(unsigned fiberCount)
- {
- void* allocation;
- if (tryFastMalloc(sizeof(URopeImpl) + (fiberCount - 1) * sizeof(Fiber)).getValue(allocation))
- return adoptRef(new (allocation) URopeImpl(fiberCount));
- return 0;
- }
-
- void initializeFiber(unsigned &index, Fiber fiber)
- {
- m_fibers[index++] = fiber;
- fiber->ref();
- m_length += fiber->length();
- }
-
- unsigned fiberCount() { return m_fiberCount; }
- Fiber& fibers(unsigned index) { return m_fibers[index]; }
-
- ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & s_refCountMask)) destructNonRecursive(); }
-
-private:
- URopeImpl(unsigned fiberCount) : UStringOrRopeImpl(ConstructRope), m_fiberCount(fiberCount) {}
-
- void destructNonRecursive();
- void derefFibersNonRecursive(Vector<URopeImpl*, 32>& workQueue);
-
- bool hasOneRef() { return (m_refCountAndFlags & s_refCountMask) == s_refCountIncrement; }
-
- unsigned m_fiberCount;
- Fiber m_fibers[1];
-
- friend class UStringOrRopeImpl;
-};
-
-inline void UStringOrRopeImpl::deref()
-{
- if (isRope())
- static_cast<URopeImpl*>(this)->deref();
- else
- static_cast<UStringImpl*>(this)->deref();
-}
-
-bool equal(const UStringImpl*, const UStringImpl*);
-
-}
+// FIXME: Remove this redundant name!
+#include <wtf/text/StringImpl.h>
+namespace JSC { typedef WebCore::StringImpl UStringImpl; }
#endif
diff --git a/JavaScriptCore/runtime/WeakGCPtr.h b/JavaScriptCore/runtime/WeakGCPtr.h
index 3ed4645..5f58374 100644
--- a/JavaScriptCore/runtime/WeakGCPtr.h
+++ b/JavaScriptCore/runtime/WeakGCPtr.h
@@ -65,6 +65,10 @@ public:
WeakGCPtr& operator=(T*);
+#if !ASSERT_DISABLED
+ bool hasDeadObject() const { return !!m_ptr; }
+#endif
+
private:
void assign(T* ptr)
{
diff --git a/JavaScriptCore/tests/perf/bench-allocate-nonretained.js b/JavaScriptCore/tests/perf/bench-allocate-nonretained.js
new file mode 100644
index 0000000..d493416
--- /dev/null
+++ b/JavaScriptCore/tests/perf/bench-allocate-nonretained.js
@@ -0,0 +1,6 @@
+(function () {
+ for (var i = 0; i < 500; ++i) {
+ for (var j = 0; j < 100000; ++j)
+ var a = {};
+ }
+})();
diff --git a/JavaScriptCore/tests/perf/bench-allocate-retained.js b/JavaScriptCore/tests/perf/bench-allocate-retained.js
new file mode 100644
index 0000000..4e6a4bd
--- /dev/null
+++ b/JavaScriptCore/tests/perf/bench-allocate-retained.js
@@ -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/JavaScriptCore/wrec/CharacterClass.cpp b/JavaScriptCore/wrec/CharacterClass.cpp
deleted file mode 100644
index e3f12f2..0000000
--- a/JavaScriptCore/wrec/CharacterClass.cpp
+++ /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/JavaScriptCore/wrec/CharacterClassConstructor.cpp b/JavaScriptCore/wrec/CharacterClassConstructor.cpp
deleted file mode 100644
index 06f4262..0000000
--- a/JavaScriptCore/wrec/CharacterClassConstructor.cpp
+++ /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/JavaScriptCore/wrec/CharacterClassConstructor.h b/JavaScriptCore/wrec/CharacterClassConstructor.h
deleted file mode 100644
index 581733d..0000000
--- a/JavaScriptCore/wrec/CharacterClassConstructor.h
+++ /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/JavaScriptCore/wrec/Escapes.h b/JavaScriptCore/wrec/Escapes.h
deleted file mode 100644
index 16c1d6f..0000000
--- a/JavaScriptCore/wrec/Escapes.h
+++ /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/JavaScriptCore/wrec/WREC.cpp b/JavaScriptCore/wrec/WREC.cpp
deleted file mode 100644
index 145a1ce..0000000
--- a/JavaScriptCore/wrec/WREC.cpp
+++ /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/JavaScriptCore/wrec/WRECFunctors.cpp b/JavaScriptCore/wrec/WRECFunctors.cpp
deleted file mode 100644
index 5f1674e..0000000
--- a/JavaScriptCore/wrec/WRECFunctors.cpp
+++ /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/JavaScriptCore/wrec/WRECFunctors.h b/JavaScriptCore/wrec/WRECFunctors.h
deleted file mode 100644
index 610ce55..0000000
--- a/JavaScriptCore/wrec/WRECFunctors.h
+++ /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/JavaScriptCore/wrec/WRECGenerator.cpp b/JavaScriptCore/wrec/WRECGenerator.cpp
deleted file mode 100644
index 7105984..0000000
--- a/JavaScriptCore/wrec/WRECGenerator.cpp
+++ /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/JavaScriptCore/wrec/WRECGenerator.h b/JavaScriptCore/wrec/WRECGenerator.h
deleted file mode 100644
index d707a6e..0000000
--- a/JavaScriptCore/wrec/WRECGenerator.h
+++ /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/JavaScriptCore/wrec/WRECParser.cpp b/JavaScriptCore/wrec/WRECParser.cpp
deleted file mode 100644
index 1709bf9..0000000
--- a/JavaScriptCore/wrec/WRECParser.cpp
+++ /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/JavaScriptCore/wrec/WRECParser.h b/JavaScriptCore/wrec/WRECParser.h
deleted file mode 100644
index a3e151b..0000000
--- a/JavaScriptCore/wrec/WRECParser.h
+++ /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/JavaScriptCore/wscript b/JavaScriptCore/wscript
index 7caf8b4..61ad1fb 100644
--- a/JavaScriptCore/wscript
+++ b/JavaScriptCore/wscript
@@ -30,7 +30,7 @@ import commands
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 = []
@@ -78,7 +78,7 @@ def build(bld):
# 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(),
@@ -89,7 +89,7 @@ def build(bld):
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(),
diff --git a/JavaScriptCore/wtf/ASCIICType.h b/JavaScriptCore/wtf/ASCIICType.h
index 0c3c29f..b43bb37 100644
--- a/JavaScriptCore/wtf/ASCIICType.h
+++ b/JavaScriptCore/wtf/ASCIICType.h
@@ -30,7 +30,6 @@
#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
diff --git a/JavaScriptCore/wtf/AlwaysInline.h b/JavaScriptCore/wtf/AlwaysInline.h
index ce27df6..34f8b74 100644
--- a/JavaScriptCore/wtf/AlwaysInline.h
+++ b/JavaScriptCore/wtf/AlwaysInline.h
@@ -59,9 +59,17 @@
#ifndef NO_RETURN
#if COMPILER(GCC)
#define NO_RETURN __attribute((__noreturn__))
-#elif COMPILER(RVCT)
+#elif COMPILER(MSVC) || COMPILER(RVCT)
#define NO_RETURN __declspec(noreturn)
#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
diff --git a/JavaScriptCore/wtf/Assertions.h b/JavaScriptCore/wtf/Assertions.h
index 0e02af5..df8646f 100644
--- a/JavaScriptCore/wtf/Assertions.h
+++ b/JavaScriptCore/wtf/Assertions.h
@@ -56,6 +56,7 @@
#endif
#ifdef NDEBUG
+/* Disable ASSERT* macros in release mode. */
#define ASSERTIONS_DISABLED_DEFAULT 1
#else
#define ASSERTIONS_DISABLED_DEFAULT 0
@@ -148,8 +149,14 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
}
#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 { \
@@ -164,7 +171,11 @@ void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChann
#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. */
diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp
index 90d1e3f..7824159 100644
--- a/JavaScriptCore/wtf/FastMalloc.cpp
+++ b/JavaScriptCore/wtf/FastMalloc.cpp
@@ -204,6 +204,16 @@ TryMallocReturnValue tryFastZeroedMalloc(size_t n)
#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)
@@ -365,10 +375,21 @@ void releaseFastMallocFreeMemory() { }
FastMallocStatistics fastMallocStatistics()
{
- FastMallocStatistics statistics = { 0, 0, 0, 0 };
+ FastMallocStatistics statistics = { 0, 0, 0 };
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)
@@ -396,7 +417,6 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
#include <algorithm>
#include <errno.h>
#include <limits>
-#include <new>
#include <pthread.h>
#include <stdarg.h>
#include <stddef.h>
@@ -411,7 +431,7 @@ extern "C" const int jscore_fastmalloc_introspection = 0;
#include <windows.h>
#endif
-#if WTF_CHANGES
+#ifdef WTF_CHANGES
#if OS(DARWIN)
#include "MallocZoneSupport.h"
@@ -460,7 +480,7 @@ namespace WTF {
#define CHECK_CONDITION ASSERT
#if OS(DARWIN)
-class Span;
+struct Span;
class TCMalloc_Central_FreeListPadded;
class TCMalloc_PageHeap;
class TCMalloc_ThreadCache;
@@ -1232,18 +1252,26 @@ template <> class MapSelector<32> {
// -------------------------------------------------------------------------
#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;
+// 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 free committed pages that we want to keep around.
static const size_t kMinimumFreeCommittedPageCount = 512;
@@ -1353,8 +1381,9 @@ class TCMalloc_PageHeap {
// 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);
@@ -1399,13 +1428,13 @@ class TCMalloc_PageHeap {
void initializeScavenger();
ALWAYS_INLINE void signalScavenger();
void scavenge();
- ALWAYS_INLINE bool shouldContinueScavenging() const;
+ ALWAYS_INLINE bool shouldScavenge() const;
#if !HAVE(DISPATCH_H)
- static NO_RETURN void* runScavengerThread(void*);
+ static NO_RETURN_WITH_VALUE void* runScavengerThread(void*);
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;
@@ -1431,7 +1460,7 @@ void TCMalloc_PageHeap::init()
#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;
@@ -1474,7 +1503,7 @@ void* TCMalloc_PageHeap::runScavengerThread(void* context)
ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
{
- if (!m_scavengeThreadActive && shouldContinueScavenging())
+ if (!m_scavengeThreadActive && shouldScavenge())
pthread_cond_signal(&m_scavengeCondition);
}
@@ -1484,15 +1513,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);
- 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()
{
- if (!m_scavengingScheduled && shouldContinueScavenging()) {
+ if (!m_scavengingScheduled && shouldScavenge()) {
m_scavengingScheduled = true;
dispatch_resume(m_scavengeTimer);
}
@@ -1502,17 +1531,12 @@ ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger()
void TCMalloc_PageHeap::scavenge()
{
- // If we've recently commited pages, our working set is growing, so now is
- // not a good time to free pages.
- if (pages_committed_since_last_scavenge_ > 0) {
- pages_committed_since_last_scavenge_ = 0;
- return;
- }
+ size_t pagesToRelease = min_free_committed_pages_since_last_scavenge_ * kScavengePercentage;
+ size_t targetPageCount = std::max<size_t>(kMinimumFreeCommittedPageCount, free_committed_pages_ - pagesToRelease);
- for (int i = kMaxPages; i >= 0 && shouldContinueScavenging(); i--) {
+ for (int i = kMaxPages; i >= 0 && free_committed_pages_ > targetPageCount; 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
+ while (!DLL_IsEmpty(&slist->normal) && free_committed_pages_ > targetPageCount) {
Span* s = slist->normal.prev;
DLL_Remove(s);
ASSERT(!s->decommitted);
@@ -1527,11 +1551,10 @@ void TCMalloc_PageHeap::scavenge()
}
}
- ASSERT(!shouldContinueScavenging());
- pages_committed_since_last_scavenge_ = 0;
+ 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;
}
@@ -1563,9 +1586,6 @@ inline Span* TCMalloc_PageHeap::New(Length n) {
if (result->decommitted) {
TCMalloc_SystemCommit(reinterpret_cast<void*>(result->start << kPageShift), static_cast<size_t>(n << kPageShift));
result->decommitted = false;
-#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
- pages_committed_since_last_scavenge_ += n;
-#endif
}
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
else {
@@ -1573,6 +1593,8 @@ inline Span* TCMalloc_PageHeap::New(Length n) {
// 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());
@@ -1634,9 +1656,6 @@ Span* TCMalloc_PageHeap::AllocLarge(Length n) {
if (best->decommitted) {
TCMalloc_SystemCommit(reinterpret_cast<void*>(best->start << kPageShift), static_cast<size_t>(n << kPageShift));
best->decommitted = false;
-#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
- pages_committed_since_last_scavenge_ += n;
-#endif
}
#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
else {
@@ -1644,6 +1663,8 @@ Span* TCMalloc_PageHeap::AllocLarge(Length n) {
// 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());
@@ -1787,6 +1808,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 (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;
@@ -1951,10 +1974,6 @@ bool TCMalloc_PageHeap::GrowHeap(Length n) {
}
ask = actual_size >> kPageShift;
-#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY
- pages_committed_since_last_scavenge_ += ask;
-#endif
-
uint64_t old_system_bytes = system_bytes_;
system_bytes_ += (ask << kPageShift);
const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift;
@@ -2352,15 +2371,15 @@ void TCMalloc_PageHeap::scavengerThread()
#endif
while (1) {
- if (!shouldContinueScavenging()) {
+ if (!shouldScavenge()) {
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);
}
- sleep(kScavengeTimerDelayInSeconds);
+ sleep(kScavengeDelayInSeconds);
{
SpinLockHolder h(&pageheap_lock);
pageheap->scavenge();
@@ -2377,7 +2396,7 @@ void TCMalloc_PageHeap::periodicScavenge()
pageheap->scavenge();
}
- if (!shouldContinueScavenging()) {
+ if (!shouldScavenge()) {
m_scavengingScheduled = false;
dispatch_suspend(m_scavengeTimer);
}
@@ -3922,6 +3941,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
@@ -3976,6 +3997,8 @@ void operator delete[](void* p, const std::nothrow_t&) __THROW {
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);
@@ -4091,7 +4114,62 @@ void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride;
#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;
@@ -4377,6 +4455,9 @@ malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enum
#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !OS(IPHONE_OS)
, 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
};
}
@@ -4408,44 +4489,9 @@ void FastMallocZone::init()
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
-#endif
+#endif // WTF_CHANGES
#endif // FORCE_SYSTEM_MALLOC
diff --git a/JavaScriptCore/wtf/FastMalloc.h b/JavaScriptCore/wtf/FastMalloc.h
index 74d4307..1ccd6a6 100644
--- a/JavaScriptCore/wtf/FastMalloc.h
+++ b/JavaScriptCore/wtf/FastMalloc.h
@@ -34,6 +34,7 @@ namespace WTF {
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)
@@ -82,10 +83,9 @@ namespace WTF {
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();
@@ -180,16 +180,17 @@ namespace WTF {
} // namespace WTF
-using WTF::fastMalloc;
-using WTF::fastZeroedMalloc;
using WTF::fastCalloc;
+using WTF::fastFree;
+using WTF::fastMalloc;
+using WTF::fastMallocSize;
using WTF::fastRealloc;
-using WTF::tryFastMalloc;
-using WTF::tryFastZeroedMalloc;
+using WTF::fastStrDup;
+using WTF::fastZeroedMalloc;
using WTF::tryFastCalloc;
+using WTF::tryFastMalloc;
using WTF::tryFastRealloc;
-using WTF::fastFree;
-using WTF::fastStrDup;
+using WTF::tryFastZeroedMalloc;
#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.
-// 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)
diff --git a/JavaScriptCore/wtf/HashCountedSet.h b/JavaScriptCore/wtf/HashCountedSet.h
index 165eb41..4ed75c5 100644
--- a/JavaScriptCore/wtf/HashCountedSet.h
+++ b/JavaScriptCore/wtf/HashCountedSet.h
@@ -43,7 +43,7 @@ namespace WTF {
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;
@@ -54,21 +54,21 @@ namespace WTF {
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&);
- // 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&);
- // clears the whole set
+ // Clears the whole set.
void clear();
private:
@@ -150,24 +150,27 @@ namespace WTF {
}
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>
- inline void HashCountedSet<Value, HashFunctions, Traits>::remove(iterator it)
+ inline bool HashCountedSet<Value, HashFunctions, Traits>::remove(iterator it)
{
if (it == end())
- return;
+ return false;
unsigned oldVal = it->second;
- ASSERT(oldVal != 0);
+ ASSERT(oldVal);
unsigned newVal = oldVal - 1;
- if (newVal == 0)
- m_impl.remove(it);
- else
+ if (newVal) {
it->second = newVal;
+ return false;
+ }
+
+ m_impl.remove(it);
+ return true;
}
template<typename Value, typename HashFunctions, typename Traits>
diff --git a/JavaScriptCore/wtf/HashMap.h b/JavaScriptCore/wtf/HashMap.h
index d63a8d4..09094d1 100644
--- a/JavaScriptCore/wtf/HashMap.h
+++ b/JavaScriptCore/wtf/HashMap.h
@@ -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 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);
+ location.second = mapped;
}
};
diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h
index 089e8ff..ac9bf60 100644
--- a/JavaScriptCore/wtf/MathExtras.h
+++ b/JavaScriptCore/wtf/MathExtras.h
@@ -123,6 +123,8 @@ inline double trunc(double num) { return num > 0 ? floor(num) : ceil(num); }
#if COMPILER(MSVC)
+inline long long abs(long long num) { return _abs64(num); }
+
inline bool isinf(double num) { return !_finite(num) && !_isnan(num); }
inline bool isnan(double num) { return !!_isnan(num); }
inline bool signbit(double num) { return _copysign(1.0, num) < 0; }
diff --git a/JavaScriptCore/wtf/OwnFastMallocPtr.h b/JavaScriptCore/wtf/OwnFastMallocPtr.h
index c88235a..8b6cbf4 100644
--- a/JavaScriptCore/wtf/OwnFastMallocPtr.h
+++ b/JavaScriptCore/wtf/OwnFastMallocPtr.h
@@ -35,7 +35,7 @@ namespace WTF {
~OwnFastMallocPtr()
{
- fastFree(m_ptr);
+ fastFree(const_cast<void*>(static_cast<const void*>(const_cast<const T*>(m_ptr))));
}
T* get() const { return m_ptr; }
diff --git a/JavaScriptCore/wtf/OwnPtr.h b/JavaScriptCore/wtf/OwnPtr.h
index b7e62b1..af1684b 100644
--- a/JavaScriptCore/wtf/OwnPtr.h
+++ b/JavaScriptCore/wtf/OwnPtr.h
@@ -40,7 +40,6 @@ namespace WTF {
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);
@@ -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; }
- 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; }
diff --git a/JavaScriptCore/wrec/WREC.h b/JavaScriptCore/wtf/OwnPtrBrew.cpp
index 13324e7..c8384e1 100644
--- a/JavaScriptCore/wrec/WREC.h
+++ b/JavaScriptCore/wtf/OwnPtrBrew.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * 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
@@ -10,10 +10,10 @@
* 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
+ * 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 INC. OR
+ * 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
@@ -23,32 +23,31 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef WREC_h
-#define WREC_h
+#include "config.h"
+#include "OwnPtr.h"
-#include <wtf/Platform.h>
+#include <AEEBitmap.h>
+#include <AEEFile.h>
+#include <AEEStdLib.h>
-#if ENABLE(WREC)
+namespace WTF {
-#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;
+void deleteOwnedPtr(IFileMgr* ptr)
+{
+ if (ptr)
+ IFILEMGR_Release(ptr);
}
-namespace JSC { namespace WREC {
-
- typedef int (*CompiledRegExp)(const UChar* input, unsigned start, unsigned length, int* output) WREC_CALL;
-
-} } // namespace JSC::WREC
+void deleteOwnedPtr(IFile* ptr)
+{
+ if (ptr)
+ IFILE_Release(ptr);
+}
-#endif // ENABLE(WREC)
+void deleteOwnedPtr(IBitmap* ptr)
+{
+ if (ptr)
+ IBitmap_Release(ptr);
+}
-#endif // WREC_h
+}
diff --git a/JavaScriptCore/wtf/OwnPtrCommon.h b/JavaScriptCore/wtf/OwnPtrCommon.h
index 6d91a54..c59fdc5 100644
--- a/JavaScriptCore/wtf/OwnPtrCommon.h
+++ b/JavaScriptCore/wtf/OwnPtrCommon.h
@@ -1,6 +1,7 @@
/*
* 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
@@ -37,6 +38,14 @@ typedef struct HPEN__* HPEN;
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)
@@ -56,6 +65,12 @@ namespace WTF {
void deleteOwnedPtr(HRGN);
#endif
+#if PLATFORM(BREWMP)
+ void deleteOwnedPtr(IFileMgr*);
+ void deleteOwnedPtr(IFile*);
+ void deleteOwnedPtr(IBitmap*);
+#endif
+
} // namespace WTF
#endif // WTF_OwnPtrCommon_h
diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h
index 9c6e44f..d7a9341 100644
--- a/JavaScriptCore/wtf/PassRefPtr.h
+++ b/JavaScriptCore/wtf/PassRefPtr.h
@@ -33,19 +33,32 @@ namespace WTF {
// 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 (UNLIKELY(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)
- inline
+#if !PLATFORM(QT)
+ ALWAYS_INLINE
+#else
+ inline
+#endif
#endif
void derefIfNotNull(T* ptr)
{
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index a6ded58..405d3e7 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -79,13 +79,21 @@
#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
-#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
+/* cross-compiling, it is not really windows */
+#undef WIN32
+#undef _WIN32
#endif
@@ -102,7 +110,28 @@
/* 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
+#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__) \
@@ -142,7 +171,7 @@
/* 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 */
@@ -162,7 +191,9 @@
/* CPU(ARM) - ARM, any version*/
#if defined(arm) \
- || defined(__arm__)
+ || defined(__arm__) \
+ || defined(ARM) \
+ || defined(_ARM_)
#define WTF_CPU_ARM 1
#if defined(__ARMEB__)
@@ -171,6 +202,7 @@
#elif !defined(__ARM_EABI__) \
&& !defined(__EABI__) \
&& !defined(__VFP_FP__) \
+ && !defined(_WIN32_WCE) \
&& !defined(ANDROID)
#define WTF_CPU_MIDDLE_ENDIAN 1
@@ -371,9 +403,6 @@
/* 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
@@ -537,6 +566,9 @@
#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)
@@ -562,10 +594,15 @@
#define HAVE_RUNLOOP_TIMER 1
#endif /* PLATFORM(MAC) && !PLATFORM(IPHONE) */
+#if PLATFORM(MAC)
+#define WTF_USE_CARBON_SECURE_INPUT_MODE 1
+#endif
+
#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
#if PLATFORM(QT) && OS(DARWIN)
@@ -608,6 +645,7 @@
#if PLATFORM(WX)
#define ENABLE_ASSEMBLER 1
+#define ENABLE_GLOBAL_FASTMALLOC_NEW 0
#if OS(DARWIN)
#define WTF_PLATFORM_CF 1
#endif
@@ -743,6 +781,11 @@
/* 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)
@@ -777,6 +820,10 @@
#define ENABLE_DASHBOARD_SUPPORT 0
#endif
+#if !defined(ENABLE_WIDGETS_10_SUPPORT)
+#define ENABLE_WIDGETS_10_SUPPORT 0
+#endif
+
#if !defined(ENABLE_INSPECTOR)
#define ENABLE_INSPECTOR 1
#endif
@@ -801,6 +848,10 @@
#define ENABLE_OPCODE_STATS 0
#endif
+#if !defined(ENABLE_GLOBAL_FASTMALLOC_NEW)
+#define ENABLE_GLOBAL_FASTMALLOC_NEW 1
+#endif
+
#define ENABLE_SAMPLING_COUNTERS 0
#define ENABLE_SAMPLING_FLAGS 0
#define ENABLE_OPCODE_SAMPLING 0
@@ -820,6 +871,10 @@
#define ENABLE_NOTIFICATIONS 0
#endif
+#if PLATFORM(IPHONE)
+#define ENABLE_TEXT_CARET 0
+#endif
+
#if !defined(ENABLE_TEXT_CARET)
#define ENABLE_TEXT_CARET 1
#endif
@@ -840,9 +895,12 @@
#endif
#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
-#elif CPU(ARM) || CPU(PPC64)
+#elif CPU(ARM) || CPU(PPC64) || CPU(MIPS)
#define WTF_USE_JSVALUE32 1
#elif OS(WINDOWS) && COMPILER(MINGW)
/* Using JSVALUE32_64 causes padding/alignement issues for JITStubArg
@@ -885,6 +943,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_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
@@ -895,6 +955,9 @@ 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
+#elif CPU(MIPS) && OS(LINUX)
+ #define ENABLE_JIT 1
+ #define WTF_USE_JIT_STUB_ARGUMENT_VA_LIST 0
#endif
#endif /* PLATFORM(QT) */
@@ -959,10 +1022,12 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
#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(ARM_TRADITIONAL) && OS(LINUX))
+ || (CPU(ARM_TRADITIONAL) && OS(LINUX)) \
+ || (CPU(MIPS) && OS(LINUX))
#define ENABLE_YARR 1
#define ENABLE_YARR_JIT 1
#endif
diff --git a/JavaScriptCore/wtf/StaticConstructors.h b/JavaScriptCore/wtf/StaticConstructors.h
new file mode 100644
index 0000000..97af339
--- /dev/null
+++ b/JavaScriptCore/wtf/StaticConstructors.h
@@ -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)
+#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)
+#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
diff --git a/JavaScriptCore/wtf/StdLibExtras.h b/JavaScriptCore/wtf/StdLibExtras.h
index 9dfb969..96a929c 100644
--- a/JavaScriptCore/wtf/StdLibExtras.h
+++ b/JavaScriptCore/wtf/StdLibExtras.h
@@ -26,7 +26,6 @@
#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
diff --git a/JavaScriptCore/wtf/TCSystemAlloc.cpp b/JavaScriptCore/wtf/TCSystemAlloc.cpp
index 4d02919..c46ff31 100644
--- a/JavaScriptCore/wtf/TCSystemAlloc.cpp
+++ b/JavaScriptCore/wtf/TCSystemAlloc.cpp
@@ -38,6 +38,7 @@
#include "Assertions.h"
#include "TCSpinLock.h"
#include "UnusedParam.h"
+#include "VMTags.h"
#if HAVE(STDINT_H)
#include <stdint.h>
@@ -178,7 +179,7 @@ static void* TryMmap(size_t size, size_t *actual_size, size_t alignment) {
void* result = mmap(NULL, size + extra,
PROT_READ | PROT_WRITE,
MAP_PRIVATE|MAP_ANONYMOUS,
- -1, 0);
+ VM_TAG_FOR_TCMALLOC_MEMORY, 0);
if (result == reinterpret_cast<void*>(MAP_FAILED)) {
mmap_failure = true;
return NULL;
diff --git a/JavaScriptCore/wtf/Threading.h b/JavaScriptCore/wtf/Threading.h
index 1599562..768aecf 100644
--- a/JavaScriptCore/wtf/Threading.h
+++ b/JavaScriptCore/wtf/Threading.h
@@ -75,7 +75,7 @@
#include <libkern/OSAtomic.h>
#elif OS(ANDROID)
#include <cutils/atomic.h>
-#elif COMPILER(GCC)
+#elif COMPILER(GCC) && !OS(SYMBIAN)
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
#include <ext/atomicity.h>
#else
@@ -86,7 +86,7 @@
#if USE(PTHREADS)
#include <pthread.h>
#elif PLATFORM(GTK)
-#include <wtf/gtk/GOwnPtr.h>
+#include "GOwnPtr.h"
typedef struct _GMutex GMutex;
typedef struct _GCond GCond;
#endif
@@ -239,7 +239,7 @@ inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Bar
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
+#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; }
diff --git a/JavaScriptCore/wtf/VMTags.h b/JavaScriptCore/wtf/VMTags.h
index 1ec79d9..6600050 100644
--- a/JavaScriptCore/wtf/VMTags.h
+++ b/JavaScriptCore/wtf/VMTags.h
@@ -26,30 +26,65 @@
#ifndef VMTags_h
#define VMTags_h
-#include <wtf/Platform.h>
-
// On Mac OS X, the VM subsystem allows tagging memory requested from mmap and vm_map
// in order to aid tools that inspect system memory use.
-#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
+#if OS(DARWIN)
#include <mach/vm_statistics.h>
-#if defined(VM_MEMORY_JAVASCRIPT_CORE) && defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) && defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
-#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_CORE)
-#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE)
+#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_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR)
#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)
+#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)
-#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)
+#else
+#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_EXECUTABLEALLOCATOR_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
diff --git a/JavaScriptCore/wtf/ValueCheck.h b/JavaScriptCore/wtf/ValueCheck.h
index cd321b8..2a86eb0 100644
--- a/JavaScriptCore/wtf/ValueCheck.h
+++ b/JavaScriptCore/wtf/ValueCheck.h
@@ -26,12 +26,7 @@
#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 {
@@ -47,13 +42,7 @@ template<typename P> struct ValueCheck<P*> {
{
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);
}
};
diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h
index 81ea321..6f55e53 100644
--- a/JavaScriptCore/wtf/Vector.h
+++ b/JavaScriptCore/wtf/Vector.h
@@ -286,6 +286,20 @@ namespace WTF {
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) {
@@ -361,6 +375,7 @@ namespace WTF {
void restoreInlineBufferIfNeeded() { }
using Base::allocateBuffer;
+ using Base::tryAllocateBuffer;
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())
@@ -538,6 +562,7 @@ namespace WTF {
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()); }
@@ -548,6 +573,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> 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&);
@@ -592,6 +618,8 @@ namespace WTF {
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;
@@ -742,6 +770,26 @@ namespace WTF {
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)
{
@@ -797,6 +845,21 @@ namespace WTF {
}
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)
{
ASSERT(!m_size);
@@ -848,6 +911,25 @@ namespace WTF {
}
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)
{
const U* ptr = &val;
diff --git a/JavaScriptCore/wtf/VectorTraits.h b/JavaScriptCore/wtf/VectorTraits.h
index bf77878..3f33b29 100644
--- a/JavaScriptCore/wtf/VectorTraits.h
+++ b/JavaScriptCore/wtf/VectorTraits.h
@@ -80,9 +80,6 @@ namespace WTF {
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> >
{
diff --git a/JavaScriptCore/wrec/CharacterClass.h b/JavaScriptCore/wtf/WTFThreadData.cpp
index 8a9d2fc..bbc9986 100644
--- a/JavaScriptCore/wrec/CharacterClass.h
+++ b/JavaScriptCore/wtf/WTFThreadData.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * 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
@@ -10,10 +10,10 @@
* 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
+ * 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 INC. OR
+ * 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
@@ -21,48 +21,34 @@
* 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
+#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)
+#if USE(JSC)
+ , m_defaultIdentifierTable(0)
+ , m_currentIdentifierTable(0)
+#endif
+{
+}
+
+WTFThreadData::~WTFThreadData()
+{
+ if (m_atomicStringTableDestructor)
+ m_atomicStringTableDestructor(m_atomicStringTable);
+}
+
+} // namespace WebCore
diff --git a/JavaScriptCore/wtf/WTFThreadData.h b/JavaScriptCore/wtf/WTFThreadData.h
new file mode 100644
index 0000000..d2c379b
--- /dev/null
+++ b/JavaScriptCore/wtf/WTFThreadData.h
@@ -0,0 +1,165 @@
+/*
+ * 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)
+ void initializeIdentifierTable(JSC::IdentifierTable* identifierTable)
+ {
+ m_defaultIdentifierTable = identifierTable;
+ m_currentIdentifierTable = identifierTable;
+ }
+
+ 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/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp b/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp
deleted file mode 100644
index dadd82e..0000000
--- a/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2010 Company 100, Inc.
- *
- * 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 "OwnPtrBrew.h"
-
-#include <AEEBitmap.h>
-#include <AEEFile.h>
-#include <AEEStdLib.h>
-
-namespace WTF {
-
-template <> void freeOwnedPtrBrew<IFileMgr>(IFileMgr* ptr)
-{
- if (ptr)
- IFILEMGR_Release(ptr);
-}
-
-template <> void freeOwnedPtrBrew<IFile>(IFile* ptr)
-{
- if (ptr)
- IFILE_Release(ptr);
-}
-
-template <> void freeOwnedPtrBrew<IBitmap>(IBitmap* ptr)
-{
- if (ptr)
- IBitmap_Release(ptr);
-}
-
-template <typename T> void freeOwnedPtrBrew(T* ptr)
-{
- FREEIF(ptr);
-}
-
-} // namespace WTF
diff --git a/JavaScriptCore/wtf/brew/OwnPtrBrew.h b/JavaScriptCore/wtf/brew/OwnPtrBrew.h
deleted file mode 100644
index 1bb44fc..0000000
--- a/JavaScriptCore/wtf/brew/OwnPtrBrew.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Collabora Ltd.
- * Copyright (C) 2010 Company 100, 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 OwnPtrBrew_h
-#define OwnPtrBrew_h
-
-#include <algorithm>
-#include <wtf/Assertions.h>
-#include <wtf/Noncopyable.h>
-
-// 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;
-
-namespace WTF {
-
-template <typename T> void freeOwnedPtrBrew(T* ptr);
-template<> void freeOwnedPtrBrew<IFileMgr>(IFileMgr*);
-template<> void freeOwnedPtrBrew<IFile>(IFile*);
-template<> void freeOwnedPtrBrew<IBitmap>(IBitmap*);
-
-template <typename T> class OwnPtrBrew : public Noncopyable {
-public:
- explicit OwnPtrBrew(T* ptr = 0) : m_ptr(ptr) { }
- ~OwnPtrBrew() { freeOwnedPtrBrew(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);
- freeOwnedPtrBrew(m_ptr);
- m_ptr = ptr;
- }
-
- void clear()
- {
- freeOwnedPtrBrew(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* OwnPtrBrew::*UnspecifiedBoolType;
- operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtrBrew::m_ptr : 0; }
-
- void swap(OwnPtrBrew& o) { std::swap(m_ptr, o.m_ptr); }
-
-private:
- T* m_ptr;
-};
-
-template <typename T> inline void swap(OwnPtrBrew<T>& a, OwnPtrBrew<T>& b)
-{
- a.swap(b);
-}
-
-template <typename T, typename U> inline bool operator==(const OwnPtrBrew<T>& a, U* b)
-{
- return a.get() == b;
-}
-
-template <typename T, typename U> inline bool operator==(T* a, const OwnPtrBrew<U>& b)
-{
- return a == b.get();
-}
-
-template <typename T, typename U> inline bool operator!=(const OwnPtrBrew<T>& a, U* b)
-{
- return a.get() != b;
-}
-
-template <typename T, typename U> inline bool operator!=(T* a, const OwnPtrBrew<U>& b)
-{
- return a != b.get();
-}
-
-template <typename T> inline typename OwnPtrBrew<T>::PtrType getPtr(const OwnPtrBrew<T>& p)
-{
- return p.get();
-}
-
-} // namespace WTF
-
-using WTF::OwnPtrBrew;
-
-#endif // OwnPtrBrew_h
diff --git a/JavaScriptCore/wtf/brew/ShellBrew.h b/JavaScriptCore/wtf/brew/ShellBrew.h
new file mode 100644
index 0000000..7416eca
--- /dev/null
+++ b/JavaScriptCore/wtf/brew/ShellBrew.h
@@ -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/JavaScriptCore/wtf/brew/SystemMallocBrew.h b/JavaScriptCore/wtf/brew/SystemMallocBrew.h
new file mode 100644
index 0000000..c973b30
--- /dev/null
+++ b/JavaScriptCore/wtf/brew/SystemMallocBrew.h
@@ -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
diff --git a/JavaScriptCore/wtf/efl/MainThreadEfl.cpp b/JavaScriptCore/wtf/efl/MainThreadEfl.cpp
new file mode 100644
index 0000000..fe32d1b
--- /dev/null
+++ b/JavaScriptCore/wtf/efl/MainThreadEfl.cpp
@@ -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/JavaScriptCore/wtf/gtk/GOwnPtr.cpp b/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
index da0d839..da0d839 100644
--- a/JavaScriptCore/wtf/gtk/GOwnPtr.cpp
+++ b/JavaScriptCore/wtf/gobject/GOwnPtr.cpp
diff --git a/JavaScriptCore/wtf/gtk/GOwnPtr.h b/JavaScriptCore/wtf/gobject/GOwnPtr.h
index 1fc594c..1fc594c 100644
--- a/JavaScriptCore/wtf/gtk/GOwnPtr.h
+++ b/JavaScriptCore/wtf/gobject/GOwnPtr.h
diff --git a/JavaScriptCore/wtf/gtk/GRefPtr.cpp b/JavaScriptCore/wtf/gobject/GRefPtr.cpp
index e7cf34b..e7cf34b 100644
--- a/JavaScriptCore/wtf/gtk/GRefPtr.cpp
+++ b/JavaScriptCore/wtf/gobject/GRefPtr.cpp
diff --git a/JavaScriptCore/wtf/gtk/GRefPtr.h b/JavaScriptCore/wtf/gobject/GRefPtr.h
index 66739ef..66739ef 100644
--- a/JavaScriptCore/wtf/gtk/GRefPtr.h
+++ b/JavaScriptCore/wtf/gobject/GRefPtr.h
diff --git a/JavaScriptCore/wtf/mac/MainThreadMac.mm b/JavaScriptCore/wtf/mac/MainThreadMac.mm
index 0ddd5f6..586ef4d 100644
--- a/JavaScriptCore/wtf/mac/MainThreadMac.mm
+++ b/JavaScriptCore/wtf/mac/MainThreadMac.mm
@@ -29,8 +29,10 @@
#import "config.h"
#import "MainThread.h"
+#import <CoreFoundation/CoreFoundation.h>
#import <Foundation/NSThread.h>
#import <wtf/Assertions.h>
+#import <wtf/Threading.h>
@interface WTFMainThreadCaller : NSObject {
}
@@ -63,9 +65,36 @@ void initializeMainThreadPlatform()
#endif
}
+static bool isTimerPosted; // This is only accessed on the 'main' thread.
+
+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);
+
+ if (isMainThread()) {
+ postTimer();
+ return;
+ }
+
#if USE(WEB_THREAD)
[staticMainThreadCaller performSelector:@selector(call) onThread:webThread withObject:nil waitUntilDone:NO];
#else
diff --git a/JavaScriptCore/wtf/qt/StringQt.cpp b/JavaScriptCore/wtf/qt/StringQt.cpp
new file mode 100644
index 0000000..b2c621a
--- /dev/null
+++ b/JavaScriptCore/wtf/qt/StringQt.cpp
@@ -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
diff --git a/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp b/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp
new file mode 100644
index 0000000..6a28e9e
--- /dev/null
+++ b/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.cpp
@@ -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/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h b/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h
new file mode 100644
index 0000000..21422f6
--- /dev/null
+++ b/JavaScriptCore/wtf/symbian/BlockAllocatorSymbian.h
@@ -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/JavaScriptCore/wtf/text/AtomicString.cpp b/JavaScriptCore/wtf/text/AtomicString.cpp
new file mode 100644
index 0000000..79b9ab5
--- /dev/null
+++ b/JavaScriptCore/wtf/text/AtomicString.cpp
@@ -0,0 +1,327 @@
+/*
+ * 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"
+
+#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
+#define ATOMICSTRING_HIDE_GLOBALS 1
+#endif
+
+#include "AtomicString.h"
+
+#include "StaticConstructors.h"
+#include "StringHash.h"
+#include <wtf/Threading.h>
+#include <wtf/HashSet.h>
+#include <wtf/WTFThreadData.h>
+
+namespace WebCore {
+
+class AtomicStringTable {
+public:
+ static AtomicStringTable* create()
+ {
+ AtomicStringTable* table = new AtomicStringTable;
+
+ WTFThreadData& data = wtfThreadData();
+ data.m_atomicStringTable = table;
+ data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
+
+ return table;
+ }
+
+ HashSet<StringImpl*>& table()
+ {
+ return m_table;
+ }
+
+private:
+ static void destroy(AtomicStringTable* table)
+ {
+ 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->setInTable();
+ }
+};
+
+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();
+ 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->setInTable();
+ }
+};
+
+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->setInTable();
+ }
+};
+
+PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length)
+{
+ if (!s)
+ return 0;
+
+ if (length == 0)
+ return StringImpl::empty();
+
+ UCharBuffer buf = { s, length };
+ 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 };
+ 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};
+ 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(StringImpl* r)
+{
+ if (!r || r->inTable())
+ return r;
+
+ if (r->length() == 0)
+ return StringImpl::empty();
+
+ StringImpl* result = *stringTable().add(r).first;
+ if (result == r)
+ r->setInTable();
+ 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 };
+ 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)
+{
+ 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);
+}
+
+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) {
+ // Initialization is not thread safe, so this function must be called from the main thread first.
+ ASSERT(isMainThread());
+
+ // 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/JavaScriptCore/wtf/text/AtomicString.h b/JavaScriptCore/wtf/text/AtomicString.h
new file mode 100644
index 0000000..9db70f4
--- /dev/null
+++ b/JavaScriptCore/wtf/text/AtomicString.h
@@ -0,0 +1,166 @@
+/*
+ * 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 FastAllocBase {
+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*);
+ static PassRefPtr<StringImpl> add(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/JavaScriptCore/wtf/text/AtomicStringImpl.h b/JavaScriptCore/wtf/text/AtomicStringImpl.h
new file mode 100644
index 0000000..d21a00a
--- /dev/null
+++ b/JavaScriptCore/wtf/text/AtomicStringImpl.h
@@ -0,0 +1,36 @@
+/*
+ * 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
+{
+};
+
+}
+
+#endif
diff --git a/JavaScriptCore/wtf/text/CString.cpp b/JavaScriptCore/wtf/text/CString.cpp
new file mode 100644
index 0000000..d93a5a3
--- /dev/null
+++ b/JavaScriptCore/wtf/text/CString.cpp
@@ -0,0 +1,102 @@
+/*
+ * 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';
+}
+
+const char* CString::data() const
+{
+ return m_buffer ? m_buffer->data() : 0;
+}
+
+char* CString::mutableData()
+{
+ copyBufferIfNeeded();
+ if (!m_buffer)
+ return 0;
+ return m_buffer->mutableData();
+}
+
+unsigned CString::length() const
+{
+ return m_buffer ? m_buffer->length() - 1 : 0;
+}
+
+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/JavaScriptCore/wtf/text/CString.h b/JavaScriptCore/wtf/text/CString.h
new file mode 100644
index 0000000..47f7675
--- /dev/null
+++ b/JavaScriptCore/wtf/text/CString.h
@@ -0,0 +1,81 @@
+/*
+ * 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;
+ char* mutableData();
+ unsigned length() const;
+
+ 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/JavaScriptCore/wtf/text/StringBuffer.h b/JavaScriptCore/wtf/text/StringBuffer.h
new file mode 100644
index 0000000..353a44a
--- /dev/null
+++ b/JavaScriptCore/wtf/text/StringBuffer.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple 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>
+
+namespace WebCore {
+
+class StringBuffer : public Noncopyable {
+public:
+ explicit StringBuffer(unsigned length)
+ : m_length(length)
+ , m_data(static_cast<UChar*>(fastMalloc(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)
+ 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;
+};
+
+}
+
+#endif
diff --git a/JavaScriptCore/wtf/text/StringHash.h b/JavaScriptCore/wtf/text/StringHash.h
new file mode 100644
index 0000000..b820004
--- /dev/null
+++ b/JavaScriptCore/wtf/text/StringHash.h
@@ -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/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp
new file mode 100644
index 0000000..287e529
--- /dev/null
+++ b/JavaScriptCore/wtf/text/StringImpl.cpp
@@ -0,0 +1,953 @@
+/*
+ * 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;
+
+namespace WebCore {
+
+static const unsigned minLengthToShare = 20;
+
+StringImpl::~StringImpl()
+{
+ ASSERT(!isStatic());
+
+ if (inTable())
+ 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();
+ }
+ }
+}
+
+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;
+}
+
+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)
+{
+ UChar* data;
+ PassRefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
+ int32_t length = m_length;
+ for (int i = 0; i < length; ++i)
+ data[i] = aChar;
+ return newImpl;
+}
+
+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;
+ 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;
+ int 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;
+
+ UChar* data;
+ PassRefPtr<StringImpl> newImpl =
+ createUninitialized(m_length - matchCount + (matchCount * repStrLength), 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;
+ int 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;
+
+ UChar* data;
+ PassRefPtr<StringImpl> newImpl =
+ createUninitialized(m_length + matchCount * (repStrLength - patternLength), 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] = 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));
+}
+
+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/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h
new file mode 100644
index 0000000..6ac9e40
--- /dev/null
+++ b/JavaScriptCore/wtf/text/StringImpl.h
@@ -0,0 +1,389 @@
+/*
+ * 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/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;
+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 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 inTable() const { return m_refCountAndFlags & s_refCountFlagInTable; }
+ void setInTable() { m_refCountAndFlags |= s_refCountFlagInTable; }
+
+ 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);
+ 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();
+
+ 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/JavaScriptCore/wtf/text/StringImplBase.h b/JavaScriptCore/wtf/text/StringImplBase.h
new file mode 100644
index 0000000..a8e3385
--- /dev/null
+++ b/JavaScriptCore/wtf/text/StringImplBase.h
@@ -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_refCountFlagInTable = 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/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp
new file mode 100644
index 0000000..a683e3d
--- /dev/null
+++ b/JavaScriptCore/wtf/text/WTFString.cpp
@@ -0,0 +1,960 @@
+/*
+ * (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, unsigned len)
+{
+ if (!str)
+ return;
+ m_impl = StringImpl::create(str, len);
+}
+
+String::String(const UChar* str)
+{
+ if (!str)
+ return;
+
+ int len = 0;
+ while (str[len] != UChar(0))
+ len++;
+
+ m_impl = StringImpl::create(str, len);
+}
+
+String::String(const char* str)
+{
+ if (!str)
+ return;
+ m_impl = StringImpl::create(str);
+}
+
+String::String(const char* str, unsigned length)
+{
+ if (!str)
+ return;
+ m_impl = StringImpl::create(str, length);
+}
+
+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();
+}
+
+UChar String::operator[](unsigned i) const
+{
+ if (!m_impl || i >= m_impl->length())
+ return 0;
+ return m_impl->characters()[i];
+}
+
+UChar32 String::characterStartingAt(unsigned i) const
+{
+ if (!m_impl || i >= m_impl->length())
+ return 0;
+ return m_impl->characterStartingAt(i);
+}
+
+unsigned String::length() const
+{
+ if (!m_impl)
+ return 0;
+ return m_impl->length();
+}
+
+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::characters() const
+{
+ if (!m_impl)
+ return 0;
+ return m_impl->characters();
+}
+
+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();
+}
+
+bool String::isEmpty() const
+{
+ return !m_impl || !m_impl->length();
+}
+
+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/JavaScriptCore/wtf/text/WTFString.h b/JavaScriptCore/wtf/text/WTFString.h
new file mode 100644
index 0000000..7c3c2dd
--- /dev/null
+++ b/JavaScriptCore/wtf/text/WTFString.h
@@ -0,0 +1,398 @@
+/*
+ * (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*, unsigned length);
+ String(const UChar*); // Specifically for null terminated UTF-16
+ String(const char*);
+ String(const char*, unsigned length);
+ 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); }
+
+ unsigned length() const;
+ const UChar* characters() const;
+ const UChar* charactersWithNullTermination();
+
+ UChar operator[](unsigned i) const; // if i >= length(), returns 0
+ 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) { if (m_impl) m_impl = m_impl->secure(aChar); }
+
+ 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; }
+ bool isEmpty() const;
+
+ 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
diff --git a/JavaScriptCore/wtf/unicode/Collator.h b/JavaScriptCore/wtf/unicode/Collator.h
index 51e8a06..fe6a809 100644
--- a/JavaScriptCore/wtf/unicode/Collator.h
+++ b/JavaScriptCore/wtf/unicode/Collator.h
@@ -29,8 +29,8 @@
#ifndef WTF_Collator_h
#define WTF_Collator_h
-#include <memory>
#include <wtf/Noncopyable.h>
+#include <wtf/PassOwnPtr.h>
#include <wtf/unicode/Unicode.h>
#if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION
@@ -47,7 +47,7 @@ namespace WTF {
~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;
diff --git a/JavaScriptCore/wtf/unicode/CollatorDefault.cpp b/JavaScriptCore/wtf/unicode/CollatorDefault.cpp
index eddbe53..4e05432 100644
--- a/JavaScriptCore/wtf/unicode/CollatorDefault.cpp
+++ b/JavaScriptCore/wtf/unicode/CollatorDefault.cpp
@@ -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.
diff --git a/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h b/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
index d72e707..46b00ea 100644
--- a/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
+++ b/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h
@@ -26,7 +26,7 @@
#define UnicodeGLib_h
#include "UnicodeMacrosFromICU.h"
-#include <wtf/gtk/GOwnPtr.h>
+#include "GOwnPtr.h"
#include <glib.h>
#include <pango/pango.h>
diff --git a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
index a1753a4..ecab5bd 100644
--- a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
+++ b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp
@@ -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.
@@ -71,11 +71,11 @@ std::auto_ptr<Collator> Collator::userDefault()
char buf[256];
if (collationOrder) {
CFStringGetCString(collationOrder, buf, sizeof(buf), kCFStringEncodingASCII);
- return std::auto_ptr<Collator>(new Collator(buf));
+ return new Collator(buf);
} else
- return std::auto_ptr<Collator>(new Collator(""));
+ return new Collator("");
#else
- return std::auto_ptr<Collator>(new Collator(0));
+ return new Collator(0);
#endif
}
diff --git a/JavaScriptCore/yarr/RegexCompiler.cpp b/JavaScriptCore/yarr/RegexCompiler.cpp
index 9cd3d12..9fbe213 100644
--- a/JavaScriptCore/yarr/RegexCompiler.cpp
+++ b/JavaScriptCore/yarr/RegexCompiler.cpp
@@ -36,6 +36,8 @@ using namespace WTF;
namespace JSC { namespace Yarr {
+#include "RegExpJitTables.h"
+
class CharacterClassConstructor {
public:
CharacterClassConstructor(bool isCaseInsensitive = false)
@@ -141,7 +143,7 @@ public:
CharacterClass* charClass()
{
- CharacterClass* characterClass = new CharacterClass();
+ CharacterClass* characterClass = new CharacterClass(0);
characterClass->m_matches.append(m_matches);
characterClass->m_ranges.append(m_ranges);
@@ -233,105 +235,6 @@ private:
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)
@@ -469,6 +372,7 @@ public:
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) {
@@ -544,6 +448,9 @@ public:
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)
diff --git a/JavaScriptCore/yarr/RegexCompiler.h b/JavaScriptCore/yarr/RegexCompiler.h
index 3ed2be9..9d2443a 100644
--- a/JavaScriptCore/yarr/RegexCompiler.h
+++ b/JavaScriptCore/yarr/RegexCompiler.h
@@ -26,13 +26,11 @@
#ifndef RegexCompiler_h
#define RegexCompiler_h
-#include <wtf/Platform.h>
-
#if ENABLE(YARR)
-#include <wtf/unicode/Unicode.h>
#include "RegexParser.h"
#include "RegexPattern.h"
+#include <wtf/unicode/Unicode.h>
namespace JSC { namespace Yarr {
diff --git a/JavaScriptCore/yarr/RegexInterpreter.cpp b/JavaScriptCore/yarr/RegexInterpreter.cpp
index d088086..c2cb1c2 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.cpp
+++ b/JavaScriptCore/yarr/RegexInterpreter.cpp
@@ -280,20 +280,6 @@ public:
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);
@@ -305,23 +291,6 @@ public:
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));
diff --git a/JavaScriptCore/yarr/RegexInterpreter.h b/JavaScriptCore/yarr/RegexInterpreter.h
index 48c9a5e..e3c3122 100644
--- a/JavaScriptCore/yarr/RegexInterpreter.h
+++ b/JavaScriptCore/yarr/RegexInterpreter.h
@@ -26,13 +26,11 @@
#ifndef RegexInterpreter_h
#define RegexInterpreter_h
-#include <wtf/Platform.h>
-
#if ENABLE(YARR)
-#include <wtf/unicode/Unicode.h>
#include "RegexParser.h"
#include "RegexPattern.h"
+#include <wtf/unicode/Unicode.h>
namespace JSC { namespace Yarr {
diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp
index fcb8d86..340b53d 100644
--- a/JavaScriptCore/yarr/RegexJIT.cpp
+++ b/JavaScriptCore/yarr/RegexJIT.cpp
@@ -40,7 +40,6 @@ using namespace WTF;
namespace JSC { namespace Yarr {
-
class RegexGenerator : private MacroAssembler {
friend void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline);
@@ -54,6 +53,16 @@ class RegexGenerator : private MacroAssembler {
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;
@@ -145,6 +154,11 @@ class RegexGenerator : private MacroAssembler {
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));
@@ -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()));
}
+
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);
@@ -636,7 +655,8 @@ class RegexGenerator : private MacroAssembler {
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);
@@ -722,7 +742,11 @@ class RegexGenerator : private MacroAssembler {
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);
@@ -1078,17 +1102,15 @@ class RegexGenerator : private MacroAssembler {
break;
case PatternTerm::TypeBackReference:
- m_generationFailed = true;
+ ASSERT_NOT_REACHED();
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:
@@ -1313,6 +1335,8 @@ class RegexGenerator : private MacroAssembler {
push(ARMRegisters::r5);
push(ARMRegisters::r6);
move(ARMRegisters::r3, output);
+#elif CPU(MIPS)
+ // Do nothing.
#endif
}
@@ -1330,6 +1354,8 @@ class RegexGenerator : private MacroAssembler {
pop(ARMRegisters::r6);
pop(ARMRegisters::r5);
pop(ARMRegisters::r4);
+#elif CPU(MIPS)
+ // Do nothing
#endif
ret();
}
@@ -1337,7 +1363,6 @@ class RegexGenerator : private MacroAssembler {
public:
RegexGenerator(RegexPattern& pattern)
: m_pattern(pattern)
- , m_generationFailed(false)
{
}
@@ -1367,15 +1392,9 @@ public:
jitObject.set(patchBuffer.finalizeCode());
}
- bool generationFailed()
- {
- return m_generationFailed;
- }
-
private:
RegexPattern& m_pattern;
Vector<AlternativeBacktrackRecord> m_backtrackRecords;
- bool m_generationFailed;
};
void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& patternString, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline)
@@ -1387,13 +1406,13 @@ void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const
numSubpatterns = pattern.m_numSubpatterns;
- RegexGenerator generator(pattern);
- generator.compile(globalData, jitObject);
-
- if (generator.generationFailed()) {
+ if (pattern.m_shouldFallBack) {
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));
+ } else {
+ RegexGenerator generator(pattern);
+ generator.compile(globalData, jitObject);
}
}
diff --git a/JavaScriptCore/yarr/RegexJIT.h b/JavaScriptCore/yarr/RegexJIT.h
index 935b9a3..7f9c16e 100644
--- a/JavaScriptCore/yarr/RegexJIT.h
+++ b/JavaScriptCore/yarr/RegexJIT.h
@@ -26,8 +26,6 @@
#ifndef RegexJIT_h
#define RegexJIT_h
-#include <wtf/Platform.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; }
- 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)
diff --git a/JavaScriptCore/yarr/RegexParser.h b/JavaScriptCore/yarr/RegexParser.h
index 64e8463..c946c2e 100644
--- a/JavaScriptCore/yarr/RegexParser.h
+++ b/JavaScriptCore/yarr/RegexParser.h
@@ -26,14 +26,12 @@
#ifndef RegexParser_h
#define RegexParser_h
-#include <wtf/Platform.h>
-
#if ENABLE(YARR)
#include <UString.h>
+#include <limits.h>
#include <wtf/ASCIICType.h>
#include <wtf/unicode/Unicode.h>
-#include <limits.h>
namespace JSC { namespace Yarr {
diff --git a/JavaScriptCore/yarr/RegexPattern.h b/JavaScriptCore/yarr/RegexPattern.h
index dd7512d..3271cc1 100644
--- a/JavaScriptCore/yarr/RegexPattern.h
+++ b/JavaScriptCore/yarr/RegexPattern.h
@@ -26,7 +26,6 @@
#ifndef RegexPattern_h
#define RegexPattern_h
-#include <wtf/Platform.h>
#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 {
+ // 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;
+ RefPtr<CharacterClassTable> m_table;
};
enum QuantifierType {
@@ -248,6 +271,7 @@ struct RegexPattern {
, m_multiline(multiline)
, m_numSubpatterns(0)
, m_maxBackReference(0)
+ , m_shouldFallBack(false)
, newlineCached(0)
, digitsCached(0)
, spacesCached(0)
@@ -269,6 +293,8 @@ struct RegexPattern {
m_numSubpatterns = 0;
m_maxBackReference = 0;
+ m_shouldFallBack = false;
+
newlineCached = 0;
digitsCached = 0;
spacesCached = 0;
@@ -335,6 +361,7 @@ struct RegexPattern {
bool m_multiline;
unsigned m_numSubpatterns;
unsigned m_maxBackReference;
+ bool m_shouldFallBack;
PatternDisjunction* m_body;
Vector<PatternDisjunction*, 4> m_disjunctions;
Vector<CharacterClass*> m_userCharacterClasses;